C++中的4种cast学习(dynamic_cast, static_cast, reinterpret_cast, const_cast)

本文详细介绍了C++中dynamic_cast、static_cast和reinterpret_cast的区别及应用场景,并通过实例演示了如何正确使用这些类型转换操作符。
  1. 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

  1. static_castreinterpret_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, 因为跟平台有关。

  1. 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;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值