【C++】【类型转换】4种类型转换
static_cast
-
完全替代C风格的类型转换,实现基本类型转换
-
对象指针转换时,可以将父类指针转换成子类指针,也可以将子类指针转换成父类指针;如果类与类之间不相关,就无法相互转换;
-
注意:如果父类指针指向一个父类对象,此时将父类指针换成子类指针虽然可以通过static_cast实现,但是这种转换不安全,如果父类指针本身就执行一个子类对象,则不存在安全问题;
#include <iostream> using namespace std; class Father{}; class Son:public Father{};; int main() { //基本类型之间的转换 int i = 1; double d = 1.5; cout << i << " " << d << endl; int d2i = static_cast<int>(d); double i2d = static_cast<double>(i); cout << i << " " << d << endl; //父子对象指针转换 Father *f1 = new Father; Father *f2 = new Son; Son *s1 = static_cast<Son*>(f1); // 转换成功,不安全 Son *s2 = static_cast<Son*>(f2); // 转换成功,安全 return 0; }
dynamic_cast
-
只能用于对象指针之间的类型转换,可以将父类指针转换为子类指针,也可以将子类指针转换成父类指针,此外转换结果也可以是引用,但是dynamic_cast并不等同于static_cast;
-
与static_cast的区别:dynamic_cast在将父类指针转换为子类指针的过程中,需要对其背后的对象类型进行检查以确保类型完全匹配,而static_cast不会这样做,只有当一个父类指向一个子类对象,并且父类中包含虚函数时,使用dynamic_cast将父类指针转换成子类指针才会成功,否则返回空指针,如果是引用则抛出异常;
#include <iostream> using namespace std; class Father{ virtual void dummy(){}; }; class Son:public Father{};; int main() { //父子对象指针转换 Father *f1 = new Father; Father *f2 = new Son; Son *s1 = dynamic_cast<Son*>(f1); // 转换失败 返回NULL if(s1 == nullptr) cout << "s1 is nullptr\n" << endl; Son *s2 = dynamic_cast<Son*>(f2); // 转换成功 if(s2 != nullptr) cout << "s2 not nullptr\n" << endl; //Son &s3 = dynamic_cast<Son&>(*f1); // 转换失败 抛出异常 /* terminate called after throwing an instance of ' std::bad_cast' what(): std::bad_cast */ Son &s4 = dynamic_cast<Son&>(*f2); // 转换成功 return 0; }
const_cast
-
可以在转换过程中增加或删除const属性,一般情况下,无法将常量指针直接赋值给普通指针,但是通过const_cast可以移除常量指针的const属性,实现const指针到非const指针的转换;
#include <iostream> using namespace std; class Test{}; int main() { const Test *t1 = new Test; Test *t2 = const_cast<Test*>(t1); // 转换成功 return 0; }
reinterpret_cast
-
可以将一种类型的指针直接转换为另一种类型的指针,不论两个类型之间是否有继承关系。reinterpret_cast可以把一个指针转换为一个整数,也可以把一个整数转换成一个指针,reinterpret_cast还经常用在不同函数指针之间的转换;
#include <iostream> using namespace std; class A{}; class B{}; int main() { A *a = new A; B *b = reinterpret_cast<B*>(a); // 转换成功 if(b != nullptr) cout << "right" << endl; return 0; }
知识的价值不在于占有,而在于使用