2

以下代码抛出 std::bad_cast

struct Foo {
    void foo () {}
};

struct Bar {
    Bar () {
        dynamic_cast <Foo &> (*this) .foo ();
    }
    virtual ~ Bar () {}
};

struct Baz : public Foo, public Bar {
};

int main ()
{
    Baz b;
}

我记得曾经阅读过 dynamic_cast 如何权衡实现性能,因为“它遍历完整的继承格”以便正确评估。编译器在这里需要做的是先向上投射,然后再向下投射。

是否可以使上述工作或我需要添加 virtual Foo* Bar::as_foo()=0;

4

4 回答 4

7

Foo 中没有虚函数,因此 dynamic_cast 完全有可能失败。需要有一个虚函数。在施工期间这样做也是一个坏主意,因为您将遇到施工订单问题。

于 2011-01-09T20:32:11.337 回答
2

假设Bar应该继承自Foo(在当前示例中不继承),您在此处看到的问题通常称为菱形问题foo您要使用哪个版本,Bar::foo()还是Foo::foo()? 您将需要指定一个虚拟继承:

struct Foo{
    ~virtual Foo(){}
     void foo(){}
};

struct Bar : virtual public Foo

struct Baz : virtual public Foo, public Bar

让它知道应该只存在一种foo(). 因此,虚拟继承用于调用foo()构造函数内的调用。

编辑:

为了清楚起见,我假设你想Bar继承自Foo. 如果您的代码中没有它,那么这就是错误转换错误的原因。没有继承层次结构Bar可以遍历到Foo. 此外,现代编译器甚至不应该在没有虚拟继承的情况下进行编译,但某些旧版编译器会很高兴地@#$#$ 它。

如果我要评论另一个答案,我最好用我自己的答案来回答!

于 2011-01-09T20:00:24.977 回答
1

您的示例中有几处错误,也许是意外?

Bar 不继承自 Foo,因此不能在 Bar 的构造函数中向下转换为 Foo。它们也不共享一个共同的继承父级,因此不能在彼此之间进行转换(横向)。你可能想要的是:

struct withFoo {
    virtual void foo () {}
    virtual ~withFoo() {}
};

struct Foo : public virtual withFoo {
};

struct Bar : public virtual withFoo {
    Bar () {
        foo();  // no need to cast!
    }
};

struct Baz : public Foo, public Bar {
};

int main ()
{
    Baz b;
    b.foo(); // because of virtual inheritance from withFoo, there is no ambiguity here 
}

希望这可以帮助!如果您需要澄清,请询问!

于 2011-01-09T20:11:59.287 回答
0

建造 Baz 涉及建造它的基地,其中之一就是酒吧。Baz 的 Bar 基础不能转换为 Foo,即使最终的 Baz 应该是。

于 2011-01-09T21:24:50.027 回答