C++ 处理不相关类型的动态强制转换 #包括 使用名称空间std; 类X{ 公众: 虚空f(){} }; 类Y{ 公众: 虚空g(){} }; int main() { X*X=新的X(); Y*Y=动态_投射(x);//A //Y*Y=静态_投射(x);//B cout

C++ 处理不相关类型的动态强制转换 #包括 使用名称空间std; 类X{ 公众: 虚空f(){} }; 类Y{ 公众: 虚空g(){} }; int main() { X*X=新的X(); Y*Y=动态_投射(x);//A //Y*Y=静态_投射(x);//B cout,c++,inheritance,C++,Inheritance,编译器不在乎,因为它是动态强制转换,y将在强制转换后NULL。动态强制转换使用运行时类型信息。因此这种情况是合法的,但它将返回NULL指针。 静态强制转换由编译器进行评估。dynamic\u cast在运行时使用RTTI执行类型检查,而static\u cast在编译时执行类型检查。因此,如果运行A将得到y==NULL 我建议您在C++类型的转换上使用.< /P> < P>动态CAST如果不能完成转换,返回null: 并搜索动态强制转换如果[通过使用动态强制转换]尝试强制转换为指针类型,而该类

编译器不在乎,因为它是
动态强制转换
y
将在强制转换后
NULL

动态强制转换使用运行时类型信息。因此这种情况是合法的,但它将返回NULL指针。
静态强制转换由编译器进行评估。

dynamic\u cast
在运行时使用RTTI执行类型检查,而
static\u cast
在编译时执行类型检查。因此,如果运行
A
将得到
y==NULL


我建议您在C++类型的转换上使用.< /P> < P>动态CAST如果不能完成转换,返回null:


并搜索动态强制转换

如果[通过使用动态强制转换]尝试强制转换为指针类型,而该类型不是参数对象的实际类型,则强制转换的结果将为NULL

#include <iostream> 
using namespace std; 
class X{ 
     public: 
     virtual void f(){} 
}; 

class Y { 
     public: 
     virtual void g() {} 
}; 

int main() 
{ 
     X * x = new X(); 
     Y* y = dynamic_cast<Y*>(x); //A 
     // Y* y = static_cast<Y*>(x);  //B 
     cout << y << endl; 
} 
Y*Y=dynamic_cast(x);//NULL,因为'x'不是'Y'`

这就是为什么不相关类型之间允许使用
动态\u cast

Y* y = dynamic_cast<Y*>(x); // NULL because `X` is not a `Y`
X类{
公众:
虚空f(){}
}; 
类Y{
公众:
虚空g(){}
};
Z类:公共X,公共Y{};
int main()
{ 
X*X=新的Z();
Y*Y=dynamic_cast(x);//编译并生成非空指针
} 

静态强制转换与动态强制转换之间存在巨大差异,我将把讨论范围缩小到对象世界

(声名狼藉的)向上投射可使用
静态投射。即:

class X{ 
     public: 
     virtual void f(){} 
}; 

class Y { 
     public: 
     virtual void g() {} 
};

class Z : public X, public Y {};

int main()
{ 
     X* x = new Z(); 
     Y* y = dynamic_cast<Y*>(x); // compiles and yields non-null pointer
} 
这将产生一个错误:编译器不知道您来自哪个基(来自
D1
的基或来自
D2
的基)

或者如果您使用了
virtual
继承:

struct Base {};
struct D1: Base {};
struct D2: Base {};
struct Derived: D1, D2 {};
编译器需要运行时信息,因此编译也会失败

然而,
dynamic\u cast
要聪明得多,尽管这是以运行时开销为代价的。编译器生成关于对象的信息,通常称为RTTI(运行时类型信息),
dynamic\u cast
将探索这些信息以允许:

强制转换取决于真正的运行时类型:

struct VDerived: virtual VBase {};
请注意,如果由于层次结构(如上面的
D1
/
D2
示例)而存在歧义,则这仍然不起作用

struct VDerived: virtual VBase {};
// will throw `bad_cast` if b is not a `Derived`
void foo(Base& b) { Derived& d = dynamic_cast<Derived&>(b); }
struct X {};
struct Y {};

void foo(X* x) { Y* y = dynamic_cast<Y*>(x); }

// If I add:
struct Z: X, Y {};

// then if x is in fact a Z, y will be non-null
void bar(VBase* vb) { VDerived* vd = dynamic_cast<VDerived*>(vb); }
void foobar(X* x)
{
   void* xAddr = dynamic_cast<void*>(x);

   Y* y = dynamic_cast<Y*>(y);
   void* yAddr = dynamic_cast<void*>(y);

   Z* z = dynamic_cast<Z*>(x);
   void* zAddr = dynamic_cast<void*>(z);
   if (z) { assert(xAddr == yAddr && xAddr == zAddr); }
}