简述:
dynamic_cast 操作符,将基类的指针或引用安全的转换为派生类的指针或引用。主要讲解,dynamic_cast操作符的原理、使用方式、编译器设置、返回值等相关知识。
dynamic_cast 操作符,将基类的指针或引用安全的转换为派生类的指针或引用。
1. 原理
将一个基类对象指针(或引用)cast (抛)到继承类指针,dynamic_cast 会根据基类指针是否真正指向继承类指针来做相应处理。
2. 返回值
对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;
对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。
3. 注意
dynamic_cast在将父类cast到子类时,父类必须要有虚函数。
4. 对编译器的要求
dynamic_cast<> 会用到RTTI技术,因此需要启动“运行时类型信息”这一选项,而在VC.net 2003中默认是关闭的。所以,需要人为的启动这一选项。否则编译器会警告:
warning C4541: “dynamic_cast”用在了带 /GR- 的多态类型“CBasic”上;可能导致不可预知的行为从而导致程序在运行时发生异常。
5. 编译器设置方法
在 Project->Setting中 C/C++ -> C++ Language中设置。
首先,dynamic_cast依赖于RTTI信息,其次,在转换时,dynamic_cast会检查转换的source对象是否真的可以转换成target类型,这种检查不是语法上的,而是真实情况的检查。
先看RTTI相关部分,通常,许多编译器都是通过vtable找到对象的RTTI信息的,这也就意味着,如果基类没有虚方法,也就无法判断一个基类指针变量所指对象的真实类型,
这时候,dynamic_cast只能用来做安全的转换,例如从派生类指针转换成基类指针。而这种转换其实并不需要dynamic_cast参与。
也就是说,dynamic_cast是根据RTTI记载的信息来判断类型转换是否合法的。
下面看一个例子:
struct B1{
virtual ~B1(){}
};
struct B2{
virtual ~B2(){}
};
struct D1 : B1, B2{};
int main()
{
D1 d;
B1* pb1 = &d;
B2* pb2 = dynamic_cast<B2*>(pb1);//L1
B2* pb22 = static_cast<B2*>(pb1); //L2
return 0;
}
上述定义中可以看到,B1和B2是不相关的类,从L1可以看到,dynamic_cast允许这种转换:只要B1存在多态方法。
L2将编译失败,static_cast并不允许两个完全不相干的类互相转换。
进一步分析可参见:http://www.cnblogs.com/weidagang2046/archive/2010/04/10/1709226.html