MEC | 条款2 最好使用C++转型操作符

条款2 最好使用C++转型操作符

文章目录

c++4个转型操作符

  • static_cast
  • const_cast
  • dynamic_cast
  • reinterpret_cast

原因是

  1. 新式转型方法容易便是出来,而且一眼能看出来是想做什么类型转换。
  2. 编译器得以判断转型错误(旧式转型无法做到)

static_cast

要从C的旧事转型,改为新的转型方法

cpp 复制代码
(type) expression

==>

static_cast<type> (expression)

static_cast 拥有与C旧事转型相同的威力和意义,以及相同的限制。

const_cast

const_cast 用来改变表达式中的常量性(constness)或易变性(volatileness)

cpp 复制代码
class Widget { ... };
 
class SpecialWidget : public Widget{ ... };

void update(SpecialWidget* psw) {}

SpecialWidget sw; // sw是一个非const对象
const SpecialWidget& csw = sw; // csw是sw的一个引用,它是一个const对象
update(&csw); // 错误,不能传递一个const SpecialWidget*变量给一个处理SpecialWidget*类型变量的函数
update(const_cast<SpecialWidget*>(&csw)); // 正确,csw的const显示地转换掉(csw和sw两个变量值在update函数中能被更新)
update((SpecialWidget*)&csw); // 同上,但用了一个更难识别的C风格的类型转换
 
Widget* pw = new SpecialWidget;
update(pw); // 错误,pw的类型是Widget*,但是update函数处理的是SpecialWidget*类型
update(const_cast<SpecialWidget*>(pw)); // 错误,const_cast仅能被用在影响constness or volatileness的地方,不能用在向继承子类进行类型转换

显然,const_cast 最常见的用途就是将某个对象的常量性去除掉

dynamic_cast

用来执行继承体系中的"安全向下转型或跨系转型动作"。

具体有2个作用:

  1. 将指向 base class objects的pointers 或 references 转型为 指向 derived(或sibling base) class objects 的 pointers 或 references,并得知转型是否成功。转型失败会返回 null 指针或 1个 expression
  2. 找出某个对象占用的内存的起始点
cpp 复制代码
class Widget { ... };
 
class SpecialWidget : public Widget{ ... };

void update(SpecialWidget* psw) {}
void updateViaRef(SpecialWidget& rsw) {}

Widget* pw2 = nullptr;
update(dynamic_cast<SpecialWidget*>(pw2)); // 正确,传递给update函数一个指针是指向变量类型为SpecialWidget的pw2的指针, 
                                           // 如果pw2确实指向一个对象,否则传递过去的将是空指针
 
Widget* pw3 = new SpecialWidget;
updateViaRef(dynamic_cast<SpecialWidget&>(*pw3)); // 正确,传递给updateViaRef函数SpecailWidget pw3指针,
                                                  // 如果pw3确实指向了某个对象,否则将抛出异常
 
double result3 = dynamic_cast<double>(firstNumber) / secondNumber; // 错误,没有继承关系
const SpecialWidget sw4;
update(dynamic_cast<SpecialWidget*>(&sw4)); // 错误,dynamic_cast不能转换掉const

dynamic_cast 只能用来协助你巡航于继承体系中。

reinterpret_cast

这个操作符的转换结果几乎总是与编译平台息息相关,所以 reinterpret_cast 不具有移植性。

reinterpret_cast 最常用的用途是转换"函数指针"类型

比如想将一下函数的一个指针放进 funcPtrArray 中

cpp 复制代码
type void (*FuncPtr); // FuncPtr 是个指针,指向某个函数
                      // 该函数无需任何自变量,返回值为void
FuncPtr funcPtrArray[10]; // funcPtrArray 是个数组,内有10个 FuncPtrs

int doSth();

funcPtrArray 内各函数指针所指函数的返回值为void,但 doSth 的返回值却是 int:

cpp 复制代码
funcPtrArray[0] = &doSomething; // 错误,类型不匹配
funcPtrArray[0] = reinterpret_cast<FuncPtr>(&doSomething); // 编译通过

转换函数指针的代码是不可移植的, C++不保证所有的函数指针都被用一样的方法表示,在一些情况下这样的转换会产生不正确的结果,所以应该避免转换函数指针类型

宏模仿新转换语法

如果编译器不支持新式转型动作,使用宏可达到同样效果

cpp 复制代码
#define static_cast(TYPE, EXPR) ((TYPE)(EXPR))
#define CONST_cast(TYPE, EXPR) ((TYPE)(EXPR))
#define  reinterpret_cast(TYPE, EXPR) ((TYPE)(EXPR))

宏方法不能保证转换安全,而且不能得知是否转换成功。


>>>>> 欢迎关注公众号【三戒纪元】 <<<<<

相关推荐
小叶学C++4 分钟前
【C++】类与对象(下)
java·开发语言·c++
NuyoahC22 分钟前
算法笔记(十一)——优先级队列(堆)
c++·笔记·算法·优先级队列
FL16238631291 小时前
[C++]使用纯opencv部署yolov11-pose姿态估计onnx模型
c++·opencv·yolo
sukalot1 小时前
windows C++-使用任务和 XML HTTP 请求进行连接(一)
c++·windows
ぃ扶摇ぅ2 小时前
Windows系统编程(三)进程与线程二
c++·windows
Mr.Z.4112 小时前
【历年CSP-S复赛第一题】暴力解法与正解合集(2019-2022)
c++
Death2002 小时前
使用Qt进行TCP和UDP网络编程
网络·c++·qt·tcp/ip
郭二哈3 小时前
C++——list
开发语言·c++·list
黑不溜秋的3 小时前
C++ 语言特性29 - 协程介绍
开发语言·c++
一丝晨光4 小时前
C++、Ruby和JavaScript
java·开发语言·javascript·c++·python·c·ruby