C++语言提供了四种类型转换
const_cast:
可以去除掉常量属性的类型转换
//const_cast
const int a = 10;
double* p1 = (double*)&a;//类型和原来的类型可以不一致,但是不安全
int* p2 = const_cast<int*>(&a);//类型和原本的类型必须匹配
//<>中必须是指针或者引用类型
//int b = const_cast<int>a;
static_cast:
提供编译器认为安全的类型转换,但是没有任何联系的类型之间的转换是不被允许的,
子类指针可以转为基类指针,但是基类指针不能转为子类指针,因为子类的大小肯定是大于等于基类的大小,子类的指针转为基类的指针之后,指向的空间变为基类的大小,可能会丢失数据,但是不会影响其他的变量,但是基类指针转为子类指针,则指向的空间增大,这就会导致可能访问非法内存,所以基类指针不能转为子类指针
//static_cast 基类类型和派生类类型之间可以转换
//Base 基类 Derivel public:Base
Derive1* p1 = nullptr;
Base* p = static_cast<Derive1*>(p1);
reinterpret_cast:
类似于C风格的强制类型转换,这种强制类型转换不安全,尽量避免使用
//reinterpret_cast
int* p = nullptr;
double* b = reinterpret_cast<double*>(p);
dynamic_cast:
主要用在继承结构中可以支持RTTI的类型识别的上下转换
RTTI:(Run-Time Type Information,运行时类型信息)是 C++ 的一种机制,它允许程序在运行时确定对象的类型
class Base {
public:virtual void func() = 0;
};class Derive1 :public Base {
public:void func() { cout << "call Derive1::func" << endl; }
};class Derive2 :public Base {
public:void func() { cout << "call Derive2::func" << endl; }void derive02func() { cout << "call Derive2::derive02func" << endl; }
};void showFunc(Base* p) {//dynamic_cast会检查p是否指向的是一个Derive2类型的对象// p->vfptr->vftable RTTI信息,如果是,dynamic_cast转换类型成功//返回Derive2对象的地址,给pd2,否则返回nullptrDerive2* pd2 = dynamic_cast<Derive2*>(p);//此处使用static_cast也可以强转成功,但是他永远都可以强转成功,不会检测是否是Derive2的对象if (pd2 != nullptr) {pd2->derive02func();}else {p->func();}}int main() {Derive1 a;Derive2 b;showFunc(&a);showFunc(&b);return 0;
}
在上面的代码中,Derive1和Derive2都继承于Base,并且重写了基类的虚函数func,在函数showFunc中,参数是基类指针,满足多态的条件(想要更深入的了解多态的原理,可以参考详细分析C++多态-CSDN博客),但是在这个函数中,我们只希望Derive2的对象执行它的另一种方法,而其他的执行原来的重写的方法,此时使用dynamic_cast对传入的参数进行类型转换,他会根据此时所指的对象找到当前类的虚表,检查它的RTTI确定是哪个类的对象,如果要转的类,就是当前对象的类,就进行转换,否则返回空。
以上就是我对C++中四种类型转换的理解,如有不足,请批评指正。