简介
类型转换的安全问题是需要考虑的重点:
- 首先是类型的窄化转化,导致数据的丢失;
- 接着是在类继承链中,将父亲对象的地址(指针)强制转换为子类的地址(指针),这就是所谓的下行转换,“下”表示沿着继承链往下走(子类的方向);反之上行转换,“上”表示沿着继承链往上走(父类的方向);
我们知道,C++类型转换可以分为为隐式类型转换和显式隐形类型转换;
隐式类型转换包括以下几种情况:
- 算术转换:在混合类型的算数表达式中,最宽的数据类型成为目标转换类型;
- 一种类型表达式赋值给另一种类型的对象:目标类型是被赋值对象的类型;
- 将一个表达式作为实参传递给函数调用,此时形参和实参类型不一致,则目标转换类型为形参的类型;
- 从一个函数返回一个表达式,表达式类型与返回类型不一致:目标类型为函数的返回类型;
那么显式类型转换呢?在C++中,有几种类型转换符:static_cast、dynamic_cast、reinterpret_cast还有const_cast等,这几种转换方式都能够提高转换的安全性;
下面将会一一介绍这几种类型转换符;
显式类型转换
static_cast
用法
statci_cast<new_type>(expression)
说明
静态转换,最像C语言风格的类型转换,但是安全性欠佳,需要程序员进行判断其是否安全;
在以下情况时,需要验证其安全性:
- 下行转换(把基类指针或引用转换成子类指针或引用);
- 把void指针转换成目标类型的指针;
- 其不能转换掉expression里的const、volitale、或者__unaligned属性;
dynamic_cast
用法
dynamic_cast<new_type>(expression)
说明
动态转换,有两个重要的约束条件,一是分别要求new_type为指针或者引用,二是要求下行转换时要求基类是多态的,也就是说基类中包含至少一个虚函数;
如果没有达到上面的要求,编译器则会报错,即使达到了要求,但是其仍然是不安全的话,dynamic_cast会识别出来,但是不抛异常,只是会将转换结果置为空;
reinpreter_cast
用法
reinpreter_cast<new_type>(expression)
说明
重解释转换,最不安全,两个没有任何关系的类指针之间都可以进行转换,还可以把整型数和地址(指针)相互转换,同样要求new_type是指针或者引用;
const_cast
用法
const_cast<new_type>(expression)
说明
常量向非常量转换,用来修改类型的const或者volatile属性,new_type和expression的类型是一样的;
并不会改变原来对象的常量属性,只是转换后的值为非常量属性;
文章借鉴: