以下代码投掷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; ?

有帮助吗?

解决方案

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

其他提示

假如说 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. 。同样,如果没有虚拟继承,现代编译器甚至不应该编译,但是某些旧版编译器会很高兴地 @#$#$ IT。

而且,如果我要对另一个答案发表评论,那么我最好按照自己的答案进行遵循!

您的示例中有几件事是错误的,也许是偶然的?

Bar不会从Foo继承,因此不能将其放在Bar构造函数中。他们也不共享共同的继承父母,因此不能在彼此之间(侧向)施放。您可能想要的是:

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 
}

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

建造一个巴兹涉及构建基地,其中之一就是酒吧。即使最终的BAZ应该是,BAZ的酒吧基地也无法铸造为Foo。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top