C++四种cast强制类型转换
转载自https://blog.csdn.net/wlx990074575/article/details/108005854
c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比如
1、你可以把一个指向const对象的指针转换成指向非const对象的指针
2、把一个指向基类对象的指针转换成指向一个派生类对象的指针
这两种转换之间的差别是巨大的,但是传统的c语言风格的类型转换没有区分这些。
还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成,(TYPE)EXPRESSION 而这样的东西在c++程序里一大堆。
所以c++为了克服这些缺点,引进了4新的类型转换操作符,他们是static_cast 、const_cast 、dynamic_cast 、reinterpret_cast
一、const_cast
int n = 5; int *k1 = const_cast<int*>(&n); //指针 *k1 = 1; int &k2 = const_cast<int&>(n); //引用 k2 = 2;
const_cast去除const(volatile)属性,将只读变为可读写;
const int a = 10; int* b = const_cast<int*>(&a); *b = 11;//指针b的属性变成可读可写
const_cast只针对指针、引用和this指针,其他情况的话就会出错,如下代码所示;
int n = 5; int k1 = const_cast<int>(n); //编译出错 k1 = 1; //编译出错
二、static_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); 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; }
三、dynamic_cast
dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,弥补了static_cast类型不安全的缺陷,比static_cast更安全
多用于有虚函数的基类与其派生类之间的转换,特点是进行运行时检测转换类型是否安全,如果转换失败返回nullptr,依赖于RTTI技术,但是有额外的函数开销,所以非必要的时候不使用。
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()函数
详细参考 https://www.cnblogs.com/xuelisheng/p/9479288.html
四、reinterpret_cast
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; }