C++ 强制类型转换对比
在 C++ 中,有 4 种强制类型转换方式,每种适用于不同的场景:
转换方式 | 语法 | 适用场景 | 安全性 | 编译检查 |
---|---|---|---|---|
static_cast | static_cast<新类型>(表达式) | 基本类型转换、父子类指针转换(非多态) | ⚠️ 部分安全(不检查动态类型) | 编译时检查 |
dynamic_cast | dynamic_cast<新类型>(表达式) | 多态类型向下转换(运行时检查) | ✅ 最安全(失败返回 nullptr ) | 运行时检查 |
const_cast | const_cast<新类型>(表达式) | 移除 const /volatile 属性 | ❌ 不安全(可能 UB) | 编译时检查 |
reinterpret_cast | reinterpret_cast<新类型>(表达式) | 任意指针/整数转换(低层操作) | ❌ 极不安全 | 编译时检查 |
1. static_cast
(静态转换)
用途:
- 基本数据类型转换(
int
→double
,float
→int
) - 父类指针/引用 → 子类指针/引用(无多态时)
- 子类指针/引用 → 父类指针/引用(安全)
void*
↔ 具体类型指针
示例:
int a = 10;
double b = static_cast<double>(a); // int → doubleBase* base = new Derived();
Derived* derived = static_cast<Derived*>(base); // 无多态时强制转换
特点:
- 编译时完成,无运行时开销
- 不检查动态类型(多态时可能不安全)
2. dynamic_cast
(动态转换)
用途:
- 多态类型的向下转换(父类 → 子类)
- 转换失败时返回
nullptr
(指针)或抛出异常(引用)
示例:
class Base { virtual void foo() {} }; // 必须有多态(虚函数)
class Derived : public Base {};Base* base = new Derived();
Derived* derived = dynamic_cast<Derived*>(base); // 成功Base* invalid = new Base();
Derived* fail = dynamic_cast<Derived*>(invalid); // 返回 nullptr
特点:
- 运行时检查类型,安全但性能较低
- 仅适用于多态类型(类有虚函数)
3. const_cast
(常量转换)
用途:
- 移除或添加
const
/volatile
属性 - 不修改底层数据,仅改变编译器解释
示例:
const int a = 10;
int* b = const_cast<int*>(&a); // 去 const
*b = 20; // 未定义行为(UB)!原对象是 constconst std::string& s = "hello";
std::string& mutable_s = const_cast<std::string&>(s); // 危险!
特点:
- ❌ 修改原
const
对象会导致未定义行为(UB) - 合法用途:调用旧式 API(如
strchr
)
4. reinterpret_cast
(重解释转换)
用途:
- 任意指针/整数之间的低层转换
- 例如:指针 → 整数、
float
→ 二进制表示
示例:
int* p = new int(42);
uintptr_t addr = reinterpret_cast<uintptr_t>(p); // 指针 → 整数float f = 3.14f;
int bits = reinterpret_cast<int&>(f); // 解释浮点为整数
特点:
- ❌ 极度不安全,完全绕过类型系统
- 仅用于特定场景(如序列化、硬件访问)
对比总结
场景 | 推荐转换 | 替代方案 |
---|---|---|
基本类型转换 | static_cast | C 风格转换 |
多态类向下转换 | dynamic_cast | typeid + static_cast (不安全) |
移除 const | const_cast | 重构代码避免 |
低层二进制操作 | reinterpret_cast | memcpy (更安全) |
黄金准则:
- 优先用
static_cast
和dynamic_cast
- 避免
const_cast
和reinterpret_cast
(除非必须) - 永远不要用 C 风格转换(如
(int)ptr
),它混合了所有强制转换的风险!