悉野小楼

导航

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

posted on 2023-08-24 20:17  悉野  阅读(107)  评论(0编辑  收藏  举报