旧式的强制类型转换
- 在早期C/C++中,显式地进行强制类型的转换有以下两种形式:
C++:18---强制类型转换(static_cast、const_cast、dynamic_cast、reinterpret_cast)一、static_cast二、const_cast三、reinterpret_cast四、dynamic_cast
C++的新式强制类型转换
C++:18---强制类型转换(static_cast、const_cast、dynamic_cast、reinterpret_cast)一、static_cast二、const_cast三、reinterpret_cast四、dynamic_cast - cast-name可以是:static_cast、const_cast、dynamic_cast、reinterpret_cast
- type是:转换的目标类型
避免强制类型转换
- 强制类型转换干扰了正常的类型检查,所以强烈建议程序员避免使用强制类型转换
- 这个建议对于reinterpret_cast尤其使用,因为此类类型转换总是充满了风险
一、static_cast
- 功能:用来强迫隐式类型转换,或称为显式的类型转换
- static_cast还可以将一个左值转换为右值引用,介绍可以参阅:https://blog.csdn.net/qq_41453285/article/details/104447573
- 例如:
- 将非const对象转换为const对象(但是不能将底层const对象转换为非const对象,这个只有const_cast才能做到)
- 将int转换为double,反之亦然
- 也可以将void*指针转换为其他类型指针,将pointer-to-base转换为pointer-to-derived
- 注意事项:
- 使用static_cast会去除编译器的警告,但是我们必须自己清楚转换有效,否则转换无效可能会产生未定义的结果
演示案例
int i = 10, j = 1;
double slope1 = i / j; //一般的强制类型转换,编译器可能会报出警告
double slope2 = static_cast<double>(j) / j; //显式地强制类型转换,编译器无警告
- 当我们把较大的算术类型赋值给较小的类型时,一般的强制类型转换编译器会发出警告
- 但是当我们使用static_cast后,编译器就不会报出警告
演示案例
- static_cast对于编译器无法自动执行的类型转换也非常有用
- 例如我们可以使用static_cast找回存在于void*指针中的值:
double num = 3.14;
void *p = # //任何非常量对象的地址都能存入void*
double *dp = static_cast<double*>(p); //将void*转换回初始的指针类型
二、const_cast
- 功能:用来将对象的常量性移除
- 注意事项:
- 只能改变运算对象的底层const
- const_cast只能改变表达式的常量属性,而不能改变表达式的数据类型
- const_cast常用于有函数重载的上下文,参阅:https://blog.csdn.net/qq_41453285/article/details/84843039
演示案例
const char *pc;
//正确,但是通过p写值是未定义的行为
char *p = const_cast<char*>(pc);
- 当我们去掉某个对象的const性质之后,编译器就不再阻止我们对该对象进行写操作了,因此写操作会产生未定义的后果
演示案例
- const_cast只能改变表达式的常量属性,而不能改变表达式的数据类型
const char* cp;
//错误,static_cast不能去除const性质
char*q = static_cast<char*>(cp);
//正确,字符串常量值可以转换为string类型
static_cast<string>(cp);
//错误,const只能去除const性质,但是不能进行数据类型的转换
const_cast<string>(cp);
三、reinterpret_cast
- 功能:通常为运算对象的位模式提供较低层次上的重新解释
- 例如将一个pointer-to-int转换诶一个int
- 使用reinterpret_cast是非常危险的,我们必须自己编写正确的代码
- reinterpret_cast本质上依赖于机器。要向安全地使用reinterpret_cast必须对设计的类型和编译器实现转换的过程都非常了解
演示案例
int *ip;
char *pc = reinterpret_cast<char*>(ip);
- 我们必须牢记pc所指的真是对象是一个int而不是字符
- 如果把pc当成普通的字符指针使用那么就会产生未定义的后果。例如:
int *ip;
char *pc = reinterpret_cast<char*>(ip);
//编译器虽然不报错,但是后果未定义
string str(pc);
四、dynamic_cast
- dunamic_cast支持运行时类型识别,在另外一篇文章介绍:https://blog.csdn.net/qq_41453285/article/details/104704568