More Effective C++--条款2: 尽量使用 C++风格的类型转换

static_cast 以下命名为A
const_cast 以下命名为B
dynamic_cast 以下命名为C
reinterpret_cast 以下命名为D
C 风格的类型转换(type)expression 以下命名为E




首先声明一点: E无所不能,从功能上可以完全取代A, B, C, D
    注意,我这里只说了 "从功能上"  注意我的措辞

为什么C++编译器要引入 A, B, C, D ? 就是因为 E 太粗鲁,太暴力,不小心引入错误了,编译器却发现不了
    这就好比C语言的数组,一不小心就越界了,就越界还好,你还把后面数据给覆盖了,找问题你就哭吧,
这就是为什么C++有容器的原因之一,你错了,只管自己错

A 几乎 就是C++版的 E
    除了  不能: -- 去除 const 属性
                -- 不能把 Struct 转换成 int
    -- 不能把 double 转换成 指针
  
B 用于转换掉 表达式  的 const 或 volatileness 属性
    如果你试图使用 const_cast 来完成 constness 或者 volatileness 属性之外的事情,你的类型转换将会被拒绝
注 : const_cast 只对 "指针&引用" 有效

class Widget {  } ;
class SpecialWidget : public Widget {  } ;

void Update(SpecialWidget* psw) ;

SpecialWidget sw ;
const SpecialWidget& csw = sw ;

Update(const_cast<SpecialWidget*>(&csw)) ; // 正确
Update((SpecialWidget*)&csw) ; // 正确 但用了C风格的类型转换 [亲测有效]

C dynamic_cast 把指向基类的指针或引用转换成指向派生类的指针或引用
转换成功,指针非空
转换失败返回空指针(当对指针进行类型转换时) 或 抛出异常(当对引用进行类型转换时)
如果没有虚函数, 即便两个类有继承关系,转换也不成功   [亲测是这样的]
  
D reinterpret_cast转换结果几乎是执行期定义。因此用 reinterpret_cast 的代码很难移植
    最普通的用途就是在函数指针类型之间的转换
typedef void (*FunPtr)() ;
FunPtr funcPtrArray[10] ;

int doSomething() ;
funcPtrArray[0] = &doSomething ; // 错误
funcPtrArray[0] = reinterpret_cast<FunPtr>(&doSomething) ; // 正确

好了,到此为止,基本上讲完了


再回到最开始,我说 E 无所不能  但是只是 "从功能上", 因为用 E 我可以模拟出 A,B,C,D
    *1 #define my_static_cast(TYPE, EXPR) ((TYPE)(EXPR))
*2 #define my_const_cast(TYPE, EXPR) ((TYPE)(EXPR))
*3 #define my_dynamic_cast(TYPE, EXPR) ((TYPE)(EXPR))
*4 #define my_reinter_cast(TYPE, EXPR) ((TYPE)(EXPR))
虽然都能达到目的,并且编译器也允许   从 "功能上" 实现了 A,B,C,D
    但是没有编译层面的安全检查
比如 *4 如果你转向的不是子类 编译器也会让你成功通过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值