强制类型转换
C++的四种强制转换
C++中的数据类型,可以分为:整形、浮点型、字符型和布尔型。四种强制转换(主要用于不同类型之间的转换)包含有
static_cast
:主要用于数据类型的强制转换,强制将一种数据类型转换为另外一种数据类型。const_cast
:主要用于去除不能被修改的常数特性,它并非去除原有变量的常量性,而是去除指向常量对象的指针或引用的常量性。==去除const
和voliate
==两个特性。reinterpret_cast
:主要用于处理无关类型的转换。该运算符不会改变括号中运算对象的值,而是对该对象从位模式上进行重新解释。dynamic_cast
:主要用于“类继承层次间的指针或引用安全地向下转型”。
static_cast
功能:主要用于数据类型的强制转换,强制将一种类型转换为另一种数据类型。例如,将浮点类型转换为整数类型。
使用方法:static<要转换的类型>(变量或表达式)
对于C语言中转换案例如下:
1 | int a=10; |
而在C++中采用static_cast
的方式如下所示
1 | int a=10; |
用法如下:
1)用于基本数据类型的转换。
2)用于类层次之间基类和派生类之间指针或者引用的转换,其中上行转换(派生类指针或引用转换为基类表示是安全的),下行转换(基类指针或引用转换为派生类指示表示由于没有动态类型检查所以是不安全的)
3)可以将空指针转换为目标类型的空指针。
4)可以将任何类型的表达式转换为void类型。
const_cast
功能:强制去除常量属性,不能用于去掉变量的常量性,只能用于去除指针或引用的常量性,将常量指针或将常量引用转换为非常量类型再进行修改。
使用情景1:在有些时候我们需要修改变量值只能拿到一个变量的常量指针,但是没有办法拿到原始变量,因此可以将该变量的常量指针转变为普通变量指针来修改值。
1 |
|
使用情景2:当需要调用一个参数不是const的函数(调用别人写的函数时),而我们要传进去的实际参数却是const的,但是我们知道该函数是不会对参数做修改的。因此我们就需要使用const_cast
去除const
限定,以便该函数能够接收这个实际参数。
1 |
|
使用情景3:const对象调用自身非const函数时。

解决方法:

reinterpret_cast
功能:主要用于处理无关类型的转换,它会产生一个新的值,这个值会与原始参数(expression)具有完全相同的比特位。总结来说reinterptr_cast
用在任意指针(或引用)类型之间的转换;以及指针于足够大的整数类型之间的转换;从整数类型(包括枚举类型)到指针类型,无视大小。**reinterpret_cast
运算符并不会改变括号中运算对象的值,而是对该对象从位运算模式上进行重新解释。**
使用案例:
对于如下代码,num是一个32位的int类型,采用16进制表示该值,内存中的存储结构如下所示,接下来使用pnum
和pstr
分别指向num的地址。而最终输出pstr
和pnum
所指向的内容时,输出的内容不同,主要原因是编译器会根据指针类型去解释所指向的内容。

1 |
|
使用场景:MSDN中给出其使用的场景用于辅助哈希函数。
1 | // expre_reinterpret_cast_Operator.cpp |
在进行哈希处理时,整数相对于指针更好处理。
注意:reinterpret_cast
不能像const_cast
那样去除const
修饰符。
1 | int main() |
上述通过reinterpret_cast
去const
限制时会报错,但是将const int*
通过reinterpret_cast
赋值给函数指针可以编译通过,理解的角度可以是由于函数指针本身就应该是一个const
类型的,在函数定义好之后所指内容不应该改变,只能通过传入参数来使用该函数。
dynamic_cast
功能:主要用于类继承层次间的指针或引用转换。主要还是执行“安全的向下转型”,也即是基类对象的指针或引用转换为同一继承层次的其他指针或引用。也可以向上转型,但由于传统方式完成向上转型是安全的,而且采用dynamic_cast
还会产生一定的开销。
向下转型分为两种情况:
- 基类指针所指对象是派生类类型的,这种转换是安全的;
- 基类指针所指对象是基类类型的,这种情况下
dynamic_cast
在运行时做检查,转换失败,返回结果为0。
1 |
|
运行结果如下:
以上介绍的是指针的向下转型,同样对于引用也可以进行向下转型。
同样对于引用类型的向上转型也是安全的,并且也可以分为两种情况(引用父类对象和子类对象),与指针唯一不同的在于不存在空引用,所有转换引用的dynamic_cast
检测失败时会抛出一个bad_cast
异常。
1 | int main() |
运行结果:
注意:在使用dynamic_cast
转换时基类必须定义一个虚函数,否则不会通过编译。当类没有虚函数表时,dynamic_cast
无法使用RTTI
不能通过编译(有待验证)。
RTTI(Run Time Type Identification)
通过运行时类型识别,程序能够使用基类指针或引用来检查这些指针或引用所指的对象的实际派生类型。