问题描述
我截断了以下代码:
#include <iostream>
#include <typeinfo>
using namespace std;
class B{
int i;
public:
B(){i = 1;}
virtual int get_i(){return i;}
};
class D: virtual public B{
int j;
public:
D(){j = 2;}
int get_i(){return B::get_i() + j;}
};
class D2: virtual public B{
int j2;
public:
int get_i(){return B::get_i() + j2;}
};
class MM: public D,public D2{
int x;
public:
MM(){
x = D::get_i() + D2::get_i();
}
int get_i(){return x;}
};
int main(){
B* o = new MM();
cout << o->get_i() << "\n";
MM* p = dynamic_cast<MM*>(o);
if(p) cout << p->get_i() << "\n";
D* p2 = dynamic_cast<D*>(o); /// Why does this dynamic_cast not return NULL?
if(p2)
cout << p2->get_i() << "\n";
}
The output will be:
我的问题是:为什么标记行上的dynamic_cast会成功?所以,如果我有这样的层次结构:
class Grandpa{...};
class Dad : public Grandpa{...};
class Son: public Dad{...};
当然了
Grandpa* grandpa = new Son();
没问题。
以下dynamic_cast
:
Dad* dad = dynamic_cast<Dad*>(grandpa);
总是成功?
这在某种程度上是合乎逻辑的,只要 Dad
指针始终可以指向 Son
对象,但我以前从未见过这种情况,我想确保我可以将其视为一般规则。
解决方法
为什么标记行上的dynamic_cast会成功?
因为对象的动态类型有一个 D
基。
将下面的dynamic_cast:
Dad* dad = dynamic_cast<Dad*>(grandpa);
总是成功?
鉴于 Grandpa* grandpa = new Son();
的前提,是的,它会成功。
但在其他情况下不会成功,例如:
Grandpa gp;
Grandpa* grandpa = &gp;
Dad* dad = dynamic_cast<Dad*>(grandpa); // is null
,
是的,只要超类类型指针所指向的对象确实是您尝试强制转换的类型的对象,dynamic_cast 就会成功。如果它不是那种类型的对象,那么 otoh,dynamic_cast 将返回一个空指针。