• 【C++之类型转换】static_cast、dynamic_cast、const_cast、reinterpret_cast用途与限制


    概述

    类型转换是将一个变量的数据类型转换为另一个数据类型的过程。
    在C++中,有四种类型转换运算符static_castdynamic_castconst_castreinterpret_cast

    1. static_cast:

    • 用途:主要用于基本数据类型和非多态类之间的转换,以及父子类之间指针或引用的转换。
    • 限制:不能用于非多态类与多态类之间的转换,也不能用于不相关类型之间的转换。
    • 示例:
      int num = 10;
      double d_num = static_cast<double>(num);
      
      class Base {};
      class Derived : public Base {};
      Base* base_ptr = new Derived;
      Derived* derived_ptr = static_cast<Derived*>(base_ptr);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    2. dynamic_cast:

    • 用途:主要用于多态类型之间的转换,可以在运行时进行类型检查,安全地进行向下转换。
    • 限制:只能用于含有虚函数的类,且转换的方向必须是合法的继承关系。
    • 此类型转换是向上是安全的,向下需要判断。
    • 示例:
      class Base {
      public:
          virtual void foo() {}
      };
      class Derived : public Base {};
      Base* base_ptr = new Derived;
      Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    3. const_cast:

    • 用途:主要用于删除常量属性,即去除指针或引用的const或volatile修饰符。
    • 限制:不能用于修改非指针或非引用类型的const属性。
    • 示例:
      const int num = 10;
      int* num_ptr = const_cast<int*>(&num);
      
      • 1
      • 2

    4. reinterpret_cast:

    • 用途:主要用于不同类型之间的强制转换,视为二进制的位模式进行转换。
    • 限制:转换的类型必须是无关联的,没有编译时检查。
    • 示例:
      int num = 10;
      double* d_ptr reinterpret_cast<double*>(&num);
      
      • 1
      • 2

    需要注意的是,类型转换应该谨慎使用,必须清楚转换操作的含义和可能的风险,以避免引发未定义行为。

    关于多态与非多态转换

    非多态类与多态类之间的转换指的是将非多态类对象转换为多态类对象,或将多态类对象转换为非多态类对象。

    举例说明,假设有一个父类Animal和两个子类Cat和Dog,其中Cat和Dog是Animal的派生类。

    非多态类转换为多态类:

    Cat* cat = new Cat(); // 非多态类对象
    Animal* animal = cat; // 将Cat对象转换为Animal对象(多态类)
    
    • 1
    • 2

    多态类转换为非多态类:

    Animal* animal = new Dog(); // 多态类对象
    Dog* dog = (Dog*)animal; // 将Animal对象(多态类)转换为Dog对象(非多态类)
    
    • 1
    • 2

    需要注意的是,在进行多态类转换时,需要确保被转换的对象实际上是目标类型或其子类的实例,否则会抛出Class Cast Exception异常。

    static_cast关于多态与非多态转换

    static_cast 用于多态类型转换是不安全的,因为 static_cast 在编译时进行转换,不会进行类型安全检查。
    如果使用 static_cast 进行多态类型转换,转换失败时不会返回空指针,而是产生一个未定义的行为。

    下面是一个例子来说明 static_cast 用于多态类型转换的问题:

    #include   
      
    class Base {  
    public:  
        virtual void print() { std::cout << "Base\n"; }  
    };  
      
    class Derived : public Base {  
    public:  
        void print() override { std::cout << "Derived\n"; }  
    };  
      
    int main() {  
        Base* basePtr = new Derived();  
      
        // 使用 static_cast 进行多态类型转换  
        Derived* derivedPtr = static_cast<Derived*>(basePtr);  
      
        // 如果转换失败,将产生未定义行为  
        derivedPtr->print();  
      
        delete basePtr;  
        return 0;  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在上面的例子中,basePtr 实际上指向一个 Derived 类型的对象。使用 static_cast 进行多态类型转换时,如果 basePtr 没有指向 Derived 类型的对象,转换将失败,导致未定义的行为。在这种情况下,程序可能会崩溃或产生不可预测的结果。

    因此,建议使用 dynamic_cast 进行多态类型转换,因为它会在运行时进行类型安全检查,并返回空指针来表示转换失败。这样可以更安全地处理多态类型转换的情况。

  • 相关阅读:
    C++ 类的继承(Inheritance)
    IDEA调试并运行Spring源码
    为什么管理类硕士(MBA/MEM/MPA)报考会成为职场人的香饽饽?
    提升开发效率的17个小工具
    C++类型转换运算符
    如何快速定位到报错日志中的关键信息,一招学会,赶快GET吧
    mmlab花朵分类结果展示(2)
    揭开程序员成功密码,聆听Java开发者分享职业规划心得,开启辉煌职场征程
    用策略模式干掉代码里大量的if-eles或则Swatch,提升B格由面向过程转为面向对象
    WEB网站安全检测系统设计与实现
  • 原文地址:https://blog.csdn.net/MrHHHHHH/article/details/133914655