横向不能dynamic_cast

时间:2015-04-12 09:16:41

标签: c++ polymorphism dynamic-cast

我偶然发现从衍生类到衍生类的侧面,并发现了我的知识差距。我一直生活在一个可能的世界 - 直到现在。而是抛出std::bad_cast。这是怎么回事?

#include <iostream>

class Base
{
protected:
    int x_;

public:
    Base(int x) : x_(x) {}
    virtual ~Base() = default;
    int x() const { return x_; }
    virtual void setX(int x) = 0;
};

class Editable : public Base // class implements setters
{
public:
    Editable(int x) : Base(x) {}
    void setX(int x) { x_ = x; }
};

class ReadOnly : public Base // class implements empty setters
{
public:
    ReadOnly(int x) : Base(x) {}
    void setX(int x) {}
};

int main()
{
    Editable editable(4);
    ReadOnly &readOnly = dynamic_cast<ReadOnly&>(editable); // std::bad_cast
}

2 个答案:

答案 0 :(得分:4)

这就是人们说dynamic_cast可以侧身投射的意思:

struct A { virtual ~A() = default; };
struct B { virtual ~B() = default; };
struct D : A, B {};

B* pb = new D();
A* pa = dynamic_cast<A*>(pb); // OK

即,如果指针指向从B*A*派生的内容,它允许您将A投射到B。为了使转换成功,仍然必须有指向指针的A子对象(或者如果要转换为引用类型,则绑定到引用)。

在您的情况下,eEditable。那里的任何地方都没有ReadOnly子对象。演员阵容失败了。

答案 1 :(得分:2)

你不是侧身.21 你是从一个基础派生到另一个基础的。

让我们假设您的演员阵容成功,并且在readOnlyInt班级中有一个名为ReadOnly的公共int成员。

编译器如何执行readonly.readOnlyInt
在投放的readOnlyInt中没有ReadOnly &,因为它实际上是Editable

横向铸造涉及多个继承结构&amp;看起来像这样:

class A {
    virtual ~A() {}
};

class B {
    virtual ~B() {}
};

class C : public A, public B {
};

int main() {
    B *b = new C();
    A *a = dymanic_cast<A *>(b);

    return 0;
}