C++98 类型转换
在 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 中的类型(如Value
、Instruction
等)。
示例: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*
)。
评论