- dynamic_cast 通常用于在run-time的时候把指向基类的指针/引用转换成指向子类的指针/引用(向下转型!),基类和子类通常都有虚函数。
一个例子:
Base *ptr = new Base();
Child * ptr2 = dynamic_cast<Child*>(ptr);
if(!ptr2)
cout<<error;
注意这里跟带虚函数的类的object的指针向上转型(动态绑定)不同 ,后者是安全的,因为子类的object的size要大于基类的object的size。但反过来就不一定安全了。编译器也不知道这个转换会不会成功。所以要进行run-time check。如果可以就转换,否则返回0(对指针)或返回一个bad_cast(对引用)。所以我们还需要一个ptr2来检查转换是否成功。
这里dynamic_cast的内部检查貌似是基于 RTII (类似于type_id()).
注意:
如果dynamic_cast转换指针失败,会生成一个空指针,但不会抛出异常。
Base *b1 = new Base;
if (Derived *d = dynamic_cast<Derived *>(b1)) { //这里会fail,因为b1本来就是Base类型的指针。
std::cout << "downcast from b1 to d successful\n";
d->name();
}
Base *b2 = new Derived;
if (Derived *d = dynamic_cast<Derived *>(b1)) { //这里会成功。
std::cout << "downcast from b1 to d successful\n";
d->name();
}
Base bb;
Derived &cc = dynamic_cast<Derived &>(bb); //失败,会抛出异常
dynamic_cast会检查struct/class的虚函数表,效率比较低,但正确性高。
下面是一个关于 dynamic_cast 的link,我觉得不错。
http://blog.youkuaiyun.com/jingjingtr/article/details/7886651
- static_cast 和reinterpret_cast 我的理解是它们都是提供编译期间的validation,但是具体什么时候cast要看情况,如果值已经定下来了就是在compile-time,否则就是在run-time。
static_cast通常是比较标准的转换,跟具体平台实现无关(portable)。而reinterpret_cast则是跟具体平台有关(non-portable)。
先看static_cast。一个例子如下:
double d1;
int i,j;
i = static_cast<int>(7.23); //compile time
scanf("%f", &d1);
j = static_cast<int>(d1); //run-time
这里我们直接用C语言的老办法写成
i = (int)7.23;
j = (int)d1;
行不行呢?我觉得效果是一样的。static_cast可以让这个代码看上去更加清晰,解释了这个cast是static的。在C++里面,如果要用cast应该尽量用这些cast表达式,而不是C的老方法,这样代码找起来也方便。
reinterpret cast 本质上也是一种static_cast,但是使用它的情况跟具体平台有关。比如说上面的例子就不能用
i = reinterpret_cast<int>(d);
用reinterpret_cast的一个例子:
p = reinterpret_cast<device *>(0xFFFFFF30);
等价于
p = (device *)0xFFFFFF30;
这个例子则不能用static_cast, 因为跟平台有关。
- const_cast 用来给object添加或消除const或volatile属性(这个其实应该叫cv_cast的)。这个cast其实最复杂。
例子1:
void fun1(int * num)
{
cout<<*num<<endl;
}
int main()
{
const int constant = 21;
fun1(const_cast<int*>(&constant));
return 0;
}
例子2:
int main()
{
int constant = 26;
const int* const_p = &constant;
int* modifier = const_cast<int*>(const_p);
*modifier = 3;
cout<< "constant: "<<constant<<endl;
cout<<"*modifier: "<<*modifier<<endl;
return 0;
}
本文详细介绍了C++中dynamic_cast、static_cast和reinterpret_cast的区别及应用场景,并通过实例演示了如何正确使用这些类型转换操作符。
1139

被折叠的 条评论
为什么被折叠?



