# 强制类型转换 ## 旧式强制类型转换 早期显式进行强制转换包含两种形式: ```C++ type(expr); //函数形式的强制类型转换 (type) expr; //C语言风格的强制类型转换 ``` ## dynamic_cast dynamic_cast支持运行时的类型识别,结果是一个左值。 ## const_cast 函数描述 ```C++ const_cast (expression) ``` 主要是用来去掉const属性,当然也可以加上const属性,去掉用的多,加上用的少,一般的类型必须要与(expression)的类型一致才语法正确。从底层看是:去掉const属性,是将变量从const区存储移动到stack区存储;加上const属性,是将变量从stack区或者heap区存储移动到const区存储。 去掉const属性:`const_cast (&num)` ,常用,因为不能将一个const变量直接赋给非const变量,所以必须要有转换这一步。 加上const属性:`const int * k = const_cast(j)` ,一般很少用,因为可以将一个非const变量直接赋给一个const变量。 使用场景 ```C++ //1.常量指针被转化成非常量指针,转换后指针指向原来的变量(即转换后的指针地址不变)。 class A{ public: A(){ m_iNum = 0; } int m_iNum; }; void foo(){ //指针指向类 const A *pca1 = new A; A *pa2 = const_cast(pca1); //常量对象转换为非常量对象 pa2->m_iNum = 200; //fine //转换后指针指向原来的对象 cout<< pca1->m_iNum <m_iNum<(&ica); *ia = 200; cout<< *ia <(a1); //常量引用转为非常量引用   a2.m_iNum = 200; //fine   cout<< a0.m_iNum << a1.m_iNum << a2.m_iNum << endl; //1 1 200 } ``` ## static_cast 任何明确定义的类型转换,只要不包含底层cont,都可以使用static_cast。 ```C++ int j; double slope = static_cast(j)/i; ``` 当需要把一个较大的数据类型赋值给较小的数据类型时,`static_cast` 非常有用。这里的强制类型转换告诉程序的读者和编译器:我们知道且不在乎潜在的精度损失。一般来说,如果编译器发现一个较大的数据类型试图赋值给较小的类型,就会给出警告信息。但是当我们执行了显式的类型转换后,警告信息就会被关闭。 有时`static_cast` 对于编译器无法自动执行的类型转换也非常有用。 ## reinterpret_cast `reinterpret_cast` 通常为运算对象的位模式提供较低层次上的重新解释。 ```C++ //例子 int *ip; char *pc = reinterpret_cast(ip); //pc所指的真实对象是一个int,而非字符,如果把pc当成字符指针去使用就可能在运行时发生错误。 string str(pc); //编译可能通过,但是运行发生错误 ``` 使用`reinterpret_cast` 是非常危险的,用pc初始化str的例子证明这个可能带来难以理解的错误,并且编译器也没有发出警告或者错误提示。`reinterpret_cast` 本质上依赖于机器,要想要安全的使用`reinterpret_cast` ,必须对涉及的类型和编译器实现转换的过程非常了解。