【C/C++】类型转换

发布于:2025-05-14 ⋅ 阅读:(13) ⋅ 点赞:(0)

🧠 C++ 四种类型转换详解

在 C++ 中,为了更安全、更明确地进行类型转换,标准提供了四种命名类型转换操作符。它们分别是:

类型转换 用途
static_cast 基础类型、向上转型、自定义类型转换
dynamic_cast 多态类的向下转型(运行时检查)
reinterpret_cast 强制解释内存布局(底层编程)
const_cast 添加/删除 const/volatile 属性

🔹 1. static_cast

📌 功能:

用于相关类型之间的转换,如基本数据类型、继承体系中的类指针/引用、支持构造函数或类型转换运算符的自定义类型。

✅ 合法用例:

double d = 3.14;
int i = static_cast<int>(d);  // 基本类型转换

class Base {};
class Derived : public Base {};

Derived d_obj;
Base* b = &d_obj;  // 向上转型(派生类对象转基类指针)

// 将基类指针转换为派生类指针(向下转型)
Derived* pd = static_cast<Derived*>(b);

⚠️ 注意事项:

  • 不进行运行时检查。
  • 可以用来调用单参数构造函数或类型转换运算符。
  • 不能用于不相关的类型(如 int*char*)。
  • 不能去除 constvolatile 属性。
  • 若不确定指针实际指向的类型,应优先使用 dynamic_cast

🔹 2. dynamic_cast

📌 功能:

用于多态类型的向下转型(从基类指针/引用转为派生类指针/引用),并在运行时进行类型检查。

✅ 合法用例:

class Base {
public:
    virtual void foo() {}  // 必须是多态类(有虚函数)
};
class Derived : public Base {};

Base* b = new Derived();
Derived* d = dynamic_cast<Derived*>(b);  // 安全的向下转型
if (d) {
    // 成功转换
}

⚠️ 注意事项:

  • 只适用于多态类型(即含有虚函数的类)。
  • 如果转换失败,返回 nullptr(对指针)或抛出异常(对引用)。
  • static_cast 更安全但性能略差。

🔹 3. reinterpret_cast

📌 功能:

最“危险”的转换方式,用于将一种类型强制解释为另一种类型,通常用于底层操作。

✅ 合法用例:

int i = 42;
void* p = &i;
int* pi = reinterpret_cast<int*>(p);  // 将 void* 转换为 int*

// 函数指针与不同类型的函数指针互转(非常底层用途)

⚠️ 注意事项:

  • 通常用于指针之间的转换。
  • 不进行类型安全性检查。
  • 可能导致未定义行为。
  • 应尽量避免使用,除非你清楚自己在做什么。

🔹 4. const_cast

📌 功能:

用于添加或移除变量的 constvolatile 属性。

✅ 合法用例:

const int a = 10;
int* b = const_cast<int*>(&a);  // 移除 const 属性
*b = 20;  // ❗❗ 未定义行为!因为原始对象是 const

⚠️ 注意事项:

  • 只能用于改变 constvolatile 属性。
  • 修改原本声明为 const 的对象内容会导致未定义行为
  • 通常用于适配遗留代码中需要非 const 参数的函数。

🧩 总结对比表

类型转换 是否允许 是否安全 使用场景
static_cast ✅ 相对安全 基础类型、向上转型、显式构造函数等
dynamic_cast ✅(仅限多态类) ✅✅ 最安全 向下转型、运行时类型检查
reinterpret_cast ⚠️ 非常危险 底层编程、内存操作
const_cast ⚠️ 慎用 添加/删除 const/volatile

📌 推荐使用顺序(按优先级)

  1. 避免使用类型转换,设计良好的类和接口可以减少转换需求。
  2. 使用 static_cast 替代传统的 (type) 强制转换。
  3. 在需要运行时检查的向下转型时使用 dynamic_cast
  4. 除非必要,不要使用 reinterpret_castconst_cast

💡 示例总结

#include <iostream>
using namespace std;

class Base {
public:
    virtual void dummy() {}
};

class Derived : public Base {};

int main() {
    // static_cast
    double d = 3.14;
    int i = static_cast<int>(d);

    // dynamic_cast
    Base* base = new Derived();
    Derived* derived = dynamic_cast<Derived*>(base);

    // reinterpret_cast
    int* ip = new int(5);
    void* vp = reinterpret_cast<void*>(ip);
    int* ip2 = reinterpret_cast<int*>(vp);

    // const_cast
    const char* str = "hello";
    char* mutable_str = const_cast<char*>(str);
    
    return 0;
}

网站公告

今日签到

点亮在社区的每一天
去签到