C++提供了四种类型转换运算符:const_cast、dynamic_cast、static_cast、reinterpret_cast
使用方法:XX_cast
1、const_cast
一般用于去除const/volatile属性,将const数据转换为非const
class Person{}; //设一个空类
int main()
{
const Person *p1=new Person();
Person *p2 = p1; //报错,const Person* 数据不能初始化Person *
Person *p2 = const_cast(p1); //p2是不带const属性的,赋值成功
Person *p3 = (Person *)p1; //同上句一样,都属于强制转换
}
2、dynamic_cast
一般用于多态类型的转换,有运行时进行安全检测
class Person {
virtual void run() {}
};
class Student :public Person {}; //公有继承
class car{};
int main()
{
Person* p1 = new Person();
Person* p2 = new Student();
//一般子类的内存空间会比父类的内存空间大,父类指针强转为子类指针会多包含一部分不属于父类的空间供子类指针访问
Student* stu1 = (Student*)p1; //不报错,但是不安全,子类指针指向父类对象会出现超出范围的访问
Student* stu2 = dynamic_cast(p2); //会被检测出不安全,使得stu2指向空(NULL)
Car *c1=(Car*)p1; //Car类与Person类无任何关联,但此时仍不报错,肯定不安全
Car *c2=dynamic_cast(p2); //dynamic_cast可以检测不安全,并使c2指向空(NULL)
}
3、static_cast
对比dynamic_cast,缺乏运行时安全检测
不能交叉转换(不是同一继承体系的,无法转换)
常用于基本数据类型的转换、非const转为const(适用范围较广)
class Person{};
class Car{};
int main()
{
int a = 10;
double d = static_cast(a); //普通数据类型,强制转换,等价于d=(double)a;
Person *p1 = new Person();
const Person *p2 = static_cast(p1);//等价于,const Person *p2 = p1;
Car *c1 = static_cast(p1);//报错,不能进行交叉转换
}
4、reinterpret_cast
属于比较底层的强制转换,没养任何类型检查和格式转换,仅仅是简单的二进制数据拷贝覆盖
可以交叉转换(没有安全检测)
可以将指针和整数互相转换
int main()
{
//在内存中以二进制方式存储,a在内存中表示为
//0000 1010 0000 0000 0000 0000 0000 0000---》转换为16进制为
//0a 00 00 00
int a=10;
//隐式转换,将a的值赋给b,此时b在内存中表示为
//00 00 00 00 00 00 24 40 (16进制)
double b = a;
//使用reinterpret_cast进行转换时,仅仅将二进制数据对应位置拷贝覆盖
//默认double c(不赋值时)在栈空间的表示为 cc cc cc cc cc cc cc cc
//此时c在内存中表示为: 0a 00 00 00 cc cc cc cc
double c = reinterpret_cast a;
}