1.简介
为什么需要四类cast强制类型转换?
因为C的强制转换表面上看起来功能强大,但是C的本身类型没有那么的安全,在强制转换时不会进行类型安全检查,所以可能会出错。
2.四类转换
C++中四种类型转换是:static_cast, dynamic_cast, const_cast, reinterpret_cast
2.1. const_cast
主要有三种使用的情况。
指针,引用和this指针,以及const转换为非const类型。
int n = 5;
int *k1 = const_cast<int*>(&n); //指针
*k1 = 1;
int &k2 = const_cast<int&>(n); //引用
k2 = 2;
const int a = 10;
int* b = const_cast<int*>(&a);
*b = 11;//指针b的属性变成可读可写
2.2static_cast
static_cast第一个作用是代替隐式转换 ,比如:
- 1、void* 转换为任意类型的指针
- 2、任意类型的指针转换为void*
- 3、编译器允许的跨类型转换,比如char类型转换为int类型,double转int型
int n = 10;
char c = 'a';
void *p = nullptr;
int *k = static_cast<int*>(p); // void* 转为 int *
n = static_cast<int>(c); //n就变成了97,ASCLL码中字符a的位置, 相当于int n = (int)c;
static_cast第二个作用是做基类与派生类的转换,派生类转换成基类是安全的,基类转换成派生类是不安全的,因为往往子类的内容比父类多。
static_cast可以将子类转换成父类,但是不提供安全性检查
class A{
public:
void m() {};
};
class B:public A//普通继承
{
};
int main() {
A* aa;
B* bb=static_cast<B*> (aa);//基类指针向下转换为派生类指针,不进行类型检查,不安全
system("pause");
return 0;
}
2.3dynamic_cast
用于动态类型转换。多用于有虚函数的基类与其派生类之间的转换,用于类层次间的向上和向下转化。只能转指针或引用。在进行下行转换时,dynamic_cast具有类型检查的功能,弥补了static_cast类型不安全的缺陷,比static_cast更安全,特点是进行运行时检测转换类型是否安全,如果转换失败返回nullptr。
class A{
public:
virtual void m() {};// C现在是 多态
};
class B:public A
{
};
int main() {
A* aa;
B* bb=dynamic_cast<B*> (aa);//基类指针向下转换为派生类指针
system("pause");
return 0;
}
RTTI是一种意思是运行时类型信息,它提供了运行时确定对象类型的方法,换句话说,RTTI是一种可以获取变量在运行时的实际指向的机制,使用了typeid()函数。
2.4reinterpret_cast
reinterpret代替显示转换,用于转换各种高风险的转换(隐式转换无法转换的)。
它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值),但是不进行检查,只是进行强制的复制,有安全隐患,一般不用。可以将int转指针。
它对原始对象的位模式提供较低层次上的重新解释(即reinterpret),完全复制二进制比特位到目标对象,转换后的值与原始对象无关但比特位一致,前后无精度损失。
int main() {
double d = 12.1;
char* p = reinterpret_cast<char*>(&d); // 将d以二进制(位模式)方式解释为char,并赋给*p
double* q = reinterpret_cast<double*>(p);
cout << *q << endl; // 12.1
system("pause");
return 0;
}