不能dynamic_cast侧身
Cannot dynamic_cast sideways
我偶然发现从派生到派生的横向转换 class 并发现了我的知识差距。直到现在,我一直生活在一个可以做到这一点的世界里。相反, 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
}
这就是人们说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
即,如果指针指向从 A
和 B
派生的东西,它允许您将 B*
转换为 A*
。要使转换成功,仍然必须有一个 A
指针指向的子对象(或绑定到的引用,如果要转换为引用类型)。
在您的例子中,e
是 Editable
。那里的任何地方都没有 ReadOnly
子对象。所以转换失败。
你没有侧身施法。
您正在从一个派生的基础转换为另一个。
假设您的转换成功了,并且在 ReadOnly
class.
中有一个名为 readOnlyInt
的 public int 成员
编译器如何执行readonly.readOnlyInt
?
铸造的 ReadOnly &
中没有 readOnlyInt
因为它实际上是 Editable
.
横向转换涉及多个继承结构,看起来像这样:
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;
}
我偶然发现从派生到派生的横向转换 class 并发现了我的知识差距。直到现在,我一直生活在一个可以做到这一点的世界里。相反, 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
}
这就是人们说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
即,如果指针指向从 A
和 B
派生的东西,它允许您将 B*
转换为 A*
。要使转换成功,仍然必须有一个 A
指针指向的子对象(或绑定到的引用,如果要转换为引用类型)。
在您的例子中,e
是 Editable
。那里的任何地方都没有 ReadOnly
子对象。所以转换失败。
你没有侧身施法。
您正在从一个派生的基础转换为另一个。
假设您的转换成功了,并且在 ReadOnly
class.
readOnlyInt
的 public int 成员
编译器如何执行readonly.readOnlyInt
?
铸造的 ReadOnly &
中没有 readOnlyInt
因为它实际上是 Editable
.
横向转换涉及多个继承结构,看起来像这样:
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;
}