在C语言中我们一般使用()进行类型转换,而在C++中,提供了四种方式的类型转换(这四种都是语言级别,不会产生额外的指令),都可以认为是类模板,实现了更为安全的类型转换。
一.const_cast
const_cast:去掉常量属性的一个类型转换,
int main() { const int a = 10; int* p1 = (int*)&a;//double* p1=(double*)&a;可行 int* p2 = const_cast<int*>(&a);//double* p2=const_cast<int*>(&a)不可行 }如图,C风格的强转与const_cas都能将const int*转换为int*,但是C风格的强转还能转换为double,char等其他类型,const_cast却不行(即const_cast必须类型对应),同时const_cast<这里面必须是指针或引用类型>(即不能将整形常量去掉const属性)。
二.static_cast
static_cast:提供编译器认为安全的类型转换,C++使用最广的类型转换。
即只有存在联系的类型之间可发生类型转换,没有联系的类型之间的转换会直接被编译器否决。
基类类型与派生类类型之间可以使用static_cast进行类型转换,是编译时期的类型转换。
三.reinterpret_cast
reinterpret_cast:类似于c风格的强制类型转换,不考虑是否安全。
四.dynamic_cast
dynamic_cast:主要用在继承结构中,可以支持RTTI类型识别的上下转换
class Base { public: virtual void show() { cout << "Base::show()" << endl; } }; class Derivel1 :public Base { public: void show() { cout << "Derivel1::show()" << endl; } }; class Derivel2 :public Base { public: void show() { cout << "Derivel2::show()" << endl; } void Derivel2show() { cout << "Derivel2::Derivel2show()" << endl; } }; void showFunc(Base* p) { Derivel2* pd = dynamic_cast<Derivel2*>(p); if (pd != nullptr) { pd->Derivel2show(); } else { p->show(); } } int main() { Derivel1 d1; Derivel2 d2; showFunc(&d1); showFunc(&d2); }如图:通常情况下,如果我们直接使用派生类重写基类的虚函数,那么我们使用基类指针指向派生类对象,默认是调用show函数,但是如果我们想要实现对于Derive2调用它内部实现的特例Derivel2show函数,
我们就需要使用dynamic_cast类型转换,dynamic_cast会检查p指针是否指向的是一个Derive2类型的对象,通过指针p访问其vfptr指针,继而访问其虚函数表,得到RTTI信息(即是运行时期的类型转换), 如果是,dynamic_cast转换类型成功,返回Derive2对象的地址,给pd2;否则返回nullptr