在C++11中新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast。新类型的强制转换可以提供更好的控制强制转换过程。
1 static_cast
static_cast <type_name> (expression)
仅当type_name可被隐式转换为expression所属的类型或expression可被隐式转换为type_name所属的类型时,上述转换才合法。
它主要有如下几种用法:
- 用于类层次结构中基类和派生类之间指针或引用的转换
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类的指针或引用转换为派生类表示),由于没有动态类型检查,所以是不安全的。 - 用于基本数据类型之间的转换,如把int转换成char。这种转换的安全也要开发人员来保证
- 把空指针转换成目标类型的空指针
- 把任何类型的表达式转换为void类型
注意:static_cast不能转换掉expression的const、volitale或者__unaligned属性。
#include <iostream>
//自定义类的转换
class A {
public:
virtual void GetInt(){} //必须有虚函数(更准确的说是虚函数表),才能使用dynamic_cast
};
class B : public A {};
class C {};
int main()
{
double dValue = 12.12;
float fValue = 3.14; // warning C4305: “初始化”: 从“double”到“float”截断
int nDValue = static_cast<int>(dValue); // 12
int nFValue = static_cast<int>(fValue); // 3
A *pA = new A;
B *pB = static_cast<B*>(pA); // 编译不会报错, B类继承于A类
pB = new B;
pA = static_cast<A*>(pB); // 编译不会报错, B类继承于A类
//C *pC = static_cast<C*>(pA); // 编译报错, C类与A类没有任何关系。error C2440: “static_cast”: 无法从“A *”转换为“C *”
}
2 const_cast
const_cast < type-id > ( expression )
该运算符用于执行只有一种用途的类型转换,即改变值为const或volatile;如果类型的其他方面也被修改,则上述类型转换将出错。
A a;
const A* pConstA = &a;
A* pNoConstA = const_cast<A*>(pConstA); //合法
B* pNoConstB = const_cast<A*>(pConstA); //非法
3 dynamic_cast
dynamic_cast < type-id > ( expression )
expression 类型是否能被安全转换为type-id,如果可以,运算符将返回对象地址,否则返回一个空指针。
通常,如果指向的对象(*pt)的类型为Type或者是从Type直接或间接派生而来的对象,则下面的表达式将指针pt转换为Type类型的指针:
dynamic_cast < Type* > ( pt )
它主要有如下几种用法
- dynamic_cast是运行时处理的,运行时要进行类型检查,而其他三种都是编译时完成的;
- 不能用于内置基本数据类型间的强制转换;
- 使用dynamic_cast进行转换时,基类中一定要有虚函数,否则编译不通过;
- dynamic_cast转换若成功,返回的是指向类的指针或引用;若失败则会返回NULL;
- 在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。向下转换的成败取决于将要转换的类型,即要强制转换的指针所指向的对象实际类型与将要转换后的类型一定要相同,否则转换失败。
#include <iostream>
//自定义类的转换
class A {
public:
virtual void GetInt(){} //必须有虚函数(更准确的说是虚函数表),才能使用dynamic_cast
};
class B : public A {};
class C {};
int main()
{
B* pB2 = new B;
A* pA2 = dynamic_cast<A*>(pB2); //up-cast ,合法
B* pB3 = dynamic_cast<B*>(pA2); //合法,dynamic_cast进行安全检查以后,认为pA2实际指向B对象
A* pA3 = new A;
//pB3 = dynamic_cast<A*>(pA3); //编译错误,error C2440,dynamic_cast进行安全检查以后,认为此转换不安全,禁止转换
delete pA3;
delete pB2;
}
4 reinterpret_cast
reinterpret_cast<type_id> (expression)
在C++语言中,reinterpret_cast主要有三种强制转换用途:改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整型转换为指针或引用类型。
type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。在使用reinterpret_cast强制转换过程仅仅只是比特位的拷贝,因此在使用过程中需要特别谨慎!
本文参考文献:
https://blog.csdn.net/qq_44065088/article/details/102842177
https://www.jianshu.com/p/c0f75ee4efd6