C++推荐使用四种标准cast:static_cast用于编译期安全转换,dynamic_cast支持多态类型运行时安全向下转型,const_cast唯一可修改cv限定符,reinterpret_cast仅限底层位重解释且极度危险。

在 C++ 中,类型转换分隐式和显式两类。显式转换推荐使用四种标准 cast:static_cast、dynamic_cast、const_cast 和 reinterpret_cast。它们比 C 风格的 (Type)expr 或函数式 Type(expr) 更安全、语义更清晰,编译器能更好检查意图并阻止危险操作。
static_cast:最常用,用于相关类型间的合理转换
适用于编译期可判定、无运行时开销的转换,比如基本类型间(int → double)、有明确转换构造函数或类型转换运算符的类对象、向上转型(派生类指针/引用 → 基类)等。它不进行运行时类型检查,也不处理 const/volatile 限定符。
- 数值转换:
double d = static_cast(42); - 向上转型(安全):
Derived d; Base* b = static_cast(&d); - 带转换函数的类:
std::string s = "hello"; std::string_view sv = static_cast<:string_view>(s); - 禁止向下转型(无运行时检查):
Base* b = new Base; Derived* d = static_cast(b); // 危险,不报错但行为未定义
dynamic_cast:唯一支持安全向下转型的运行时检查机制
仅适用于多态类型(含虚函数的类),用于指针或引用的向下转型(基类 → 派生类)或跨继承体系的横向转型。它在运行时检查对象实际类型,失败时对指针返回 nullptr,对引用抛出 std::bad_cast 异常。
- 安全向下转型:
Base* b = new Derived; Derived* d = dynamic_cast(b); // 成功返回有效指针 - 失败处理(指针):
if (d) { /* 安全使用 */ } - 失败处理(引用):
try { Derived& dr = dynamic_cast(*b); } catch (const std::bad_cast&) { /* 处理错误 */ } - 不能用于非多态类型:
struct A {}; A a; int* p = dynamic_cast(&a); // 编译错误
const_cast:唯一能添加或移除 const/volatile 限定符的 cast
只改变对象的 cv-qualifier(const 或 volatile),不改变类型本身。典型用途是调用接受非 const 参数但逻辑上不修改数据的旧式 C API。注意:若原对象本身是 const,通过 const_cast 修改会导致未定义行为。
立即学习“C++免费学习笔记(深入)”;
- 移除 const:
const int ci = 42; int* p = const_cast(&ci); *p = 100; // ❌ 未定义行为(ci 是字面量或栈上 const 对象) - 合法场景:
void legacy_func(char*); const std::string s = "hello"; legacy_func(const_cast(s.c_str())); // ✅ c_str() 返回 const char*,但函数不修改内容 - 不能用于转换其他类型:
const_cast(&i); // 编译错误
reinterpret_cast:底层位模式重解释,极度危险,慎用
直接按位重新解释对象的二进制表示,无视类型系统。可用于指针与整数互转、不同指针类型互转(如 char* ↔ int*)、函数指针转换等。它绕过所有类型安全机制,极易引发未定义行为,应仅在底层系统编程、序列化、硬件交互等极少数场景使用,并加清晰注释。
- 指针转整数:
uintptr_t addr = reinterpret_cast(&x); -
字节级访问:
float f = 3.14f; uint32_t bits = reinterpret_cast(f); // 获取 IEEE754 表示 - 禁止用于无关类类型转换:
reinterpret_cast(&base_obj); // ❌ 不安全,可能破坏对象布局 - 替代方案优先考虑 union(C++11 起支持类型别名)或 std::bit_cast(C++20)
选 cast 的核心原则:用最弱约束满足需求的那个。优先 static_cast;需要运行时类型安全就用 dynamic_cast;必须改 cv 限定符才用 const_cast;只有明确需要位重解释且理解后果时才用 reinterpret_cast。滥用 reinterpret_cast 或绕过 dynamic_cast 直接 static_cast 向下转型,是 C++ 程序崩溃和安全漏洞的常见源头。











