欢迎光临散文网 会员登陆 & 注册

Effective C++ 第二十七条 Minimize casting.

2023-01-28 07:03 作者:九思519  | 我要投稿

尽量少做转型动作

C++的设计目标之一就是保证“类型错误”绝不可能发生。但是 cast 破坏了类型系统。

C++ 中有新旧两种转换方式:

旧式:

  • (T) expression

  • T(expression)

这两种就是将 expression 转为 T 类型

新式:

  • const_cast 将对象的常量性去除,也就是 const → non-const

  • dynamic_cast 用于 base 和 derived 之间的转换,主要执行 “安全向下转型”,向上转换总是成功且安全,向下转换不都是成功的,对于指针如果不成功返回空指针,对于引用如果不成功抛出异常。

  • reinterpret_cast 不会变成任何机器指令,也就是没有真正转换,只是告诉编译器要将数据当作什么类型来处理而不真正转换为该类型。不能用来处理 cv 类型。

  • static_cast 用来强迫隐式转换,将 non-const 转换为 const,int转换为double,但不能将 const 转换为 non-const。

C++ 的转换不同于 C、java等,C++的转换可能会导致指针的值改变,一个 Derived 对象 d,base指针指向 d 的时候有一个地址,derived 类型的指针指向 d 的时候又有一个地址,而且两个地址可以不相同。一旦设计多重继承,指针类型转换就有可能出错。由于地址的计算方式随着编译器不同而不同,在这个平台这样算行得通,换个平台也许就不行了。

我们在 derived 中执行 virtual 函数的时候首先调用 base 中改函数

这段代码就隐藏了一下易错点,如我们预期那样,*this (derived) 被转换为了 base,但是如果 fun 涉及到成员变量修改,那么就会引发歧义。*this 变成了 base 类型,但是代码中 fun 不是 this 调用的,而是 static_cast<base>(*this) 返回的一个临时变量执行的 fun,也就是说如果 fun 涉及成员变量修改,对 this 没有任何影响。而 static_cast 之后的语句又是对 this 进行操作的。

dynamic_cast 是处理以下情况,你想调用 derived 的函数,但你只有且只能使用一个 base 指针。你可以这样做

千万不要使用第一种,dynamic开销很大,使用 type 2 更为安全和高效。

绝对要避免的就是使用“连串”的 dynamic_cast,比如这样


总结:

  • 尽量避免转型,在注意效率的代码中避免 dynamic_cast

  • 如果转型是必要的,最好隐藏在某个函数后面,而不用显示写出来

  • 使用新型转型,不要使用旧型,新型容易被分辨,出错也容易定位


Effective C++ 第二十七条 Minimize casting.的评论 (共 条)

分享到微博请遵守国家法律