C++类型转换导引

  

“尽量少做转型动作”

—— Effective C++》条款27

 

1. 引言

    本文源自在工作中的一点疑惑,先看一下下面的代码。这是一个使用了ACE架构的系统中的一段代码,它使用ACE_Message_Block将一个任务对象指针添加在执行器executorDataProcessing中。

 

即便你不了解ACE的使用方式也没有关系,我们并不关注ACE,它只是一个引子。那么,reinterpret_cast的含义?为什么要使用reinterpret_cast?何时使用reinterpret_cast?类型转换还有哪几种?

 

2. 四种C++新式转型

1reinterpret_cast<type_id>(expression)

type_id可以是指针,引用,基本类型。

reinterpret_cast运算符用来将一种类型的指针转变为另一种类型的指针,也用在将整型量转为指针,或将指针转为整型量。

需要注意的是,基本类型之间的转换不能使用reinterpret_cast进行转换,但是可以通过引用来进行,但是正确性不能保证。

2static_cast<type_id>(expression)

static_cast不同于是dynamic_cast,没有运行时类型检查用于基本类型之间的转换,其转换的安全性要由程序开发者来承担。用于类层次结构中基类和子类之间指针或引用的转换,进行上行转换(把子类的指针或引用转换成基类的指针或引用)是安全的;进行下行转换(把基类指针或引用转换成子类的指针或引用)时,由于没有运行时类型检查,所以是不安全的。

需要注意:不能在无关的指针之间使用static_cast进行强制转换

3dynamic_cast<type_id>(expression)

该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_caststatic_cast的效果是一样的;在进行下行转换时,dynamic_cast具有运行时类型检查的功能,比static_cast更安全。

4const_cast<type_id>(expression) 

该运算符用来修改类型的constvolatile__unaligned 属性。除了constvolatile__unaligned 修饰之外,type_idexpression的类型是一样的。

常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

 

3. 类型转换使用导引(后续可能还会添加)

1)若要消除对象(包括基本数据类型)的常量性,请使用const_cast

2)若要完成从基类对象向继承类对象的“安全向下转型”,请使用dynamic_cast

3)若要完成从继承类对象向基类对象的“向上转型”,请使用static_cast

4)若要完成两种类型指针间的转型,或者整型量与某类型指针间的转型,请使用reinterpret_cast

5)若要完成基本数据类型间的转型,请使用static_cast

 

4. 总结

为什么说上面的四种转型是“新式转型”呢?实际上在C++中还有两种旧式风格转型,包括C风格的转型:

Texpression    // expression转型为T

以及函数风格的转型:

Texpression    // expression转型为T

相对于旧式转型,四种新式转型应该优先选择,原因有二:

1)它们很容易在代码中被辨识出来,继而得以简化“找出类型系统在哪个地点被破坏”的过程。

2)各转型动作的目标愈窄化,编译器愈可能诊断出错误的运行。

 

5. 参考

1)C++标准转换运算符dynamic_cast


题外话

    如果可以,尽量避免转型,特别是在注重效率的代码中避免使用dynamic_casts。如果有个设计需要转型动作,试着开发无需转型的替代设计。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值