以下代码抛出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;
?
答案 0 :(得分:7)
Foo中没有虚函数,因此dynamic_cast非常有必要失败。需要有一个虚拟功能。在施工期间这样做也是一个坏主意,因为您将遇到施工订单问题。
答案 1 :(得分:2)
假设Bar
应该继承自Foo
(当前示例中没有),您在此处看到的问题通常被称为diamond problem。您要使用哪个版本的foo
,Bar::foo()
或Foo::foo()
?您将需要指定虚拟继承:
struct Foo{
~virtual Foo(){}
void foo(){}
};
struct Bar : virtual public Foo
struct Baz : virtual public Foo, public Bar
让它知道应该只存在一种foo()
。因此,virtual inheritance用于在构造函数中调用foo()
的调用。
编辑:
要明确的是,我假设您希望Bar
继承Foo
。如果你的代码中没有那个,那么这就是错误的转换错误的原因。 Bar
没有继承层次结构可以遍历到Foo
。此外,现代编译器甚至不应该在没有虚拟继承的情况下进行编译,但是某些遗留编译器很乐意@#$#$ up。
如果我要评论另一个答案,我最好按照自己的答案进行评论!
答案 2 :(得分: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
}
希望这有帮助!如果您需要澄清,请询问!
答案 3 :(得分:0)
构建Baz涉及构建其基础,其中一个是Bar。即使最终的Baz应该是,Baz的Bar基地也不能投入Foo。