强制类型转换
C++提供了四个强制类型转换的关键字:
static_cast
const_cast
reinterpret_cast
- ``dynamic_cast`
static_cast
1 | static_cast<目标类型>(表达式) |
1 | int num = 2; |
该运算符将表达式转换为目标类型。但没有进行运行时类型检查来保证转换的安全性。
主要用法
- 用于类层次结构中父类和子类之间指针或引用的转换.进行上行转换是安全的(即将子类的指针或引用转换成父类是正确的);进行下行转换的时候,由于没有动态类型检查,所以是不安全的。继承必须为public
- 用于基本类型之间的转换,如
int
与char
,安全性也需要程序员来保证 - 把空指针转换为目标类型的空指针
1 | class Person |
const_cast
const_cast
是c++中专用于处理与const相关的强制类型转换的关键字
其功能为:为一个变量重新设定其const描述.
即:const_cast
可以为一个变量强行增加或删除其const限定.
需要明确的是,即使用户通过const_cast强行去除了const属性,也不代表当前变量从不可变变为了可变。const_cast只是使得用户接管了编译器对于const限定的管理权,故用户必须遵守“不修改变量”的承诺。如果违反此承诺,编译器也不会因此而引发编译时错误,但可能引发运行时错误。
- const_cast可用于更改const成员函数内的非const类成员。
- const_cast可用于将const数据传递给不接收const的函数。
- const_cast<>里边的内容必须是引用或者指针。
- const_cast也可以用来抛弃
volatile
和__unaligned
属性。
1 | class Student |
在const成员函数fun()
中,编译器将“this”
视为“ const student const this”
,即“this”
是指向常量对象的常量指针,因此编译器不允许通过以下方式更改数据成员“这个”指针。const_cast将“this”
指针的类型更改为“student const this”
。
const_cast比简单类型转换更安全。从某种意义上讲,如果强制类型与原始对象不相同,则强制转换不会发生,这是比较安全的。
1 | int a=20; |
reinterpret_cast
reinterpret
,即重新解释.
该强制类型转换的作用是提供某个变量在底层数据上的重新解释.
当我们对一个变量使用reinterpret_cast
后,编译器将无视任何不合理行为,强行将被转换变量的内存数据重解释为某个新的类型。用于进行各种不同类型的指针之间、不同类型的引用之间以及指针和能容纳指针的整数类型之间的转换。转换时,执行的是逐个比特复制的操作。 它不检查指针类型和指针所指向的数据是否相同。
需要注意的是,reinterpret_cast
要求转换的两个数据所占用的内存大小一致,否则会引发编译时错误.
1 | data_type *var_name = reinterpret_cast <data_type *>(pointer_variable); |
使用 reinterpret_cast 的目的:
- reinterpret_cast是一种非常特殊且危险的类型转换操作符。并且建议使用适当的数据类型使用它,即(指针数据类型应与原始数据类型相同)。
- 它可以将任何指针类型转换为任何其他数据类型。
- 当我们要使用位时使用它。
- 它仅用于将任何指针转换为原始类型。
- 布尔值将转换为整数值,即0表示false,1表示true。
1 | class A { |
dynamic_cast
dynamic
用于在运行时实现向下类型转换。
1 | dynamic_cast <type-id> (expression) |
将expression
转换为type-id
类型,type-id
必须是类的指针,类的引用或者是void,
如果type-id
是一个指针,那么expression
也是一个指针,是引用的话同为引用
特点如下:
- 它是在运行是进行处理的,其余三个都是在编译时完成. 运行时进行类型检查
- 不能用于内置的基本数据类型之间的强制转换
- dynamic_cast 要求 <> 内所描述的目标类型必须为指针或引用。dynamic_cast 转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回
nullptr
。 - 在类的转换时,在类层次上进行向上转换(子类指针指向父类指针),与
static_cast
的效果是一样的。在进行父类指针向子类指针的转换时,dynamic_cast
具有类型检查的功能,比static_cast
更安全。 - 向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。在C++中,编译期的类型转换有可能会在运行时出现错误,特别是涉及到类对象的指针或引用操作时,更容易产生错误。
dynamic_cast
操作符则可以在运行期对可能产生问题的类型转换进行测试。 - 使用 dynamic_cast 进行转换的,基类中一定要有虚函数,否则编译不通过(类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意义)。这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表。
1 | class AA { |