在 C++ 中,类型转换运算符xxx_cast)提供了更安全、更明确的类型转换方式,替代了 C 风格的强制类型转换。以下是标准 C++ 中四种核心类型转换的详细介绍、应用场景及对比:

static_cast

主要用途是以下四种:

  • 基础的类型转换(例如int 和double 的转换)
  • 显示父子类指针?引用转换(无多态时)
  • 将void*转换为其他指针类型
  • 隐式转换的显式表达
    示例代码:
int a = 10;
double b = static_cast<double>(a);  // 基础类型转换

class Base {};
class Derived : public Base {};
Derived d;
Base* base_ptr = static_cast<Base*>(&d);  // 向上(父类)转换(安全)

void* p = &a;
int* int_ptr = static_cast<int*>(p);     // void* → int*

注意子转父类不要使用static_cast!
并且此时不进行运行时类型检查

dynamic_cast

主要用途是两种:

  • 多态类型的向下转换(父类指针/引用→子类)。
  • 运行时检查类型安全性(失败返回 nullptr 或抛出异常)。
class Base { virtual void foo() {} };  // 必须含虚函数
class Derived : public Base {};

Base* base_ptr = new Derived;
Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);  // 成功

Base* another_base = new Base;
Derived* bad_cast = dynamic_cast<Derived*>(another_base); // 失败,返回 nullptr
  • 依赖 RTTI(运行时类型信息),可能影响性能。
  • 仅适用于含虚函数的类(多态类型)。
  • 对引用转换失败会抛出 std::bad_cast 异常。

const_cast

主要用途是两种:

  • 移除或添加 const/volatile 限定符
  • 主要用于兼容旧代码或特定 API(如修改第三方库中本应为 const 的参数)。
const int a = 10;
int* mutable_ptr = const_cast<int*>(&a);  // 移除 const
*mutable_ptr = 20;  // 未定义行为(若原对象是 const)!

void log(char* str);  // 第三方函数,参数应为 const char*
const char* msg = "Hello";
log(const_cast<char*>(msg));  // 强制去除 const

reinterpret_cast

主要用途是两种:

  • 低级别位模式重新解释(如指针↔整数、不相关类型指针互转)。
  • 常见于系统编程、网络协议解析等场景。
int num = 0x12345678;
char* bytes = reinterpret_cast<char*>(&num);  // 将 int 视为字节数组

struct Packet { int id; char data[100]; };
Packet pkt;
char* buffer = reinterpret_cast<char*>(&pkt);  // 结构体→字节流

uintptr_t ptr_value = reinterpret_cast<uintptr_t>(&num);  // 指针→整数

dyn_cast (LLVM 扩展)

  • LLVM 项目自定义的类型转换,用于其类型系统的安全检查。
  • 类似 dynamic_cast,但针对 LLVM IR 中的类型(如 ValueInstruction 等)。
    示例:
llvm::Value* val = ...;
if (auto* inst = llvm::dyn_cast<llvm::Instruction>(val)) {
  // 成功转换为 Instruction 类型
}

对比总结

转换方式 检查时机 适用场景 安全性
static_cast 编译时 显式类型转换、父子类向上转换 较高
dynamic_cast 运行时 多态类型的向下转换 高(有检查)
const_cast 编译时 修改 const/volatile 限定符 低(需谨慎)
reinterpret_cast 编译时 底层位模式转换 极低

其实static_cast 就是安全子类转父类,不安全父类转子类
对应dynamic_casr 是安全父类转子类,子类转父类不使用这种

在 LLVM 中,dyn_cast 作用是将基类指针(如 Value*)转换为派生类指针(如 Instruction*)。