C++11 四种强制类型转换的区别
static_cast: 指针强转, 如果某个基类有多个子类, 基类的指针实际是指向A类的对象, 但使用强转为B类对象, 运行时会报错, 静态强转没做检测
dynamic_cast: 只能用于虚函数类, 子类与父类指针互转, 会检测, 转换失败为返回空, 不会崩
const_cast: 用于转换常量, 修改常量, 先用一个常量指针指向原来常量, 再用const_cast把这个常量指针转为普通指针, 再修改值(后面只能指针)
reinterpret_cast: 重新解释, 一个类继续于多个父类, 每个父类都一个相同名字的函数, 调用时系统不知道调用哪个函数, 可以使用重新解释为某个父类指针(后面指针)
static_pointer_cast,dynamic_pointer_cast,const_pointer_cast,reinterpret_pointer_cast 这四个宏转对象上面4种但转为shared_ptr
#include <iostream> using namespace std; class BaseClass { public: virtual void Action() { cout << "BaseClass Action!\n"; } }; class ChildClass : public BaseClass { public: ChildClass() {}; ChildClass(int a) { age = a; } virtual void Action() override { cout << "ChildClass Action!\n"; } int age; }; class ThirdClass { }; class Union { public: void Say() {cout << "Union'Say\n";} }; class Bag { public: void Say() { cout << "Bag'Say\n"; } }; class Player : public Union, Bag { public: void Say() { cout << "Player'Say\n"; } }; /// <summary> /// 总结: /// static_cast: 指针强转, 如果某个基类有多个子类, 基类的指针实际是指向A类的对象, 但使用强转为B类对象, 运行时会报错, 静态强转没做检测 /// dynamic_cast: 只能用于虚函数类, 子类与父类指针互转, 会检测, 转换失败为返回空, 不会崩 /// const_cast: 用于转换常量, 修改常量, 先用一个常量指针指向原来常量, 再用const_cast把这个常量指针转为普通指针, 再修改值(后面只能指针) /// reinterpret_cast: 重新解释, 一个类继续于多个父类, 每个父类都一个相同名字的函数, 调用时系统不知道调用哪个函数, 可以使用重新解释为某个父类指针(后面指针) /// static_pointer_cast,dynamic_pointer_cast,const_pointer_cast,reinterpret_pointer_cast 这四个宏转对象上面4种但转为shared_ptr /// </summary> /// <returns></returns> int main() { //static_pointer_cast与dynamic_pointer_cast测试 shared_ptr<ChildClass> ptrChildClass = make_shared<ChildClass>(); //shared_ptr<BaseClass> ptrClass = make_shared<ChildClass>(); //报错, 不能这样写 //shared_ptr<BaseClass> ptrClass = (shared_ptr<BaseClass>*)make_shared<ChildClass>(); //报错, 不支持 //shared_ptr<ChildClass> ptr = dynamic_cast<ChildClass>(ptrChildClass); // 报错 dynamic_cast是用来转换new之类的指针的 //shared_ptr<ChildClass> ptr = dynamic_pointer_cast<ChildClass>(ptrChildClass); shared_ptr<BaseClass> ptrParent = dynamic_pointer_cast<BaseClass>(ptrChildClass); //子类转父类的指针 ptrParent->Action(); shared_ptr<ChildClass> ptrChildClass2 = static_pointer_cast<ChildClass>(ptrParent); //父类转向子类的指针 ptrChildClass2->Action(); //动态转换失败会返回空, 静态这儿是编译不过(可能其它编译器编译过, 运行也会崩的) shared_ptr<ThirdClass> ptrThird = dynamic_pointer_cast<ThirdClass>(ptrParent); if (!ptrThird) { cout << "ptrThird is nullptr" << endl; } //const_cast测试 先用一个常量指针指向原常量, 然后用const_cast把常量指针转成普通指针, 再修改原数据 const ChildClass child(4); //child.age = 5; //修改不了 cout << child.age << endl; const ChildClass* pChild = &child; //pChild->age = 5; //修改不了 ChildClass* tmp = const_cast<ChildClass*>(pChild); tmp->age = 3; cout << child.age << endl; const int a = 10; const int* p = &a; int* q; q = const_cast<int*>(p); *q = 20; //fine cout << a << " " << *p << " " << *q << endl; cout << &a << " " << p << " " << q << endl; //reinterpret_cast测试 Player player; player.Say(); // auto bag = reinterpret_cast<Bag>(player); //编译不过, 提示出错 // Bag b = (Bag)(player);//编译出错 Bag* b = (Bag*)(&player); //C式强转 b->Say(); auto myunion = reinterpret_cast<Union*>(&player); //重解释 myunion->Say(); system("pause"); return 0; }
参考1:https://blog.csdn.net/qq_21989927/article/details/111226696
参考2:https://blog.csdn.net/sunlin972913894/article/details/108427587