C++风格的类型转换:
static_cast<>
,dynamic_cast<>
,const_cast<>
,reinterpret_cast<>
它们比传统的 C 风格强制转换(如 (T)x
)更安全、更清晰、更可控,每种转换都有明确的使用范围。
🔹1. static_cast<>
✅ 用于:
- 编译时已知的类型安全转换;
- 类之间的上转型(派生类 → 基类);
- 内置类型之间的转换(如
int
→double
); - 用户自定义类型间的转换(通过构造函数或转换运算符);
- 去掉
void*
→ 某类型的指针(前提你知道类型)。
🚫 不能:
- 去除
const
; - 做 RTTI 检查(运行时类型信息);
- 执行任意位模式转换。
🧠 示例:
class Base {};
class Derived : public Base {};
Derived d;
Base* b1 = static_cast<Base*>(&d); // ✅ 派生 -> 基类(安全)
double dval = static_cast<double>(3); // ✅ int -> double
🔹2. dynamic_cast<>
✅ 用于:
- 多态类型之间的转换(需要至少一个虚函数);
- 通常用于基类 → 派生类 的安全转换;
- 转换失败时返回
nullptr
(指针)或抛出std::bad_cast
(引用); - 运行时检查类型是否合法。
🚫 不能:
- 用于非多态类型;
- 转换非相关类;
- 去除
const
。
🧠 示例:
class Base {
public:
virtual ~Base() = default; // 必须有虚函数
};
class Derived : public Base {};
Base* b = new Derived;
Derived* d = dynamic_cast<Derived*>(b); // ✅ 安全向下转换
Base* b2 = new Base;
Derived* d2 = dynamic_cast<Derived*>(b2); // ❌ d2 == nullptr,b2不是Derived
🔹3. const_cast<>
✅ 用于:
- 去除
const
或volatile
修饰; - 常用于调用旧接口或类成员中需要“合法修改”的情况。
🚫 危险:
- 如果你修改了一个原本是
const
定义的对象,会引起未定义行为(UB); - 不涉及类型变化,只是属性变化。
🧠 示例:
void func(int* p) { *p = 42; }
const int x = 10;
func(const_cast<int*>(&x)); // ❌ UB!x 是 const 定义的
int y = 20;
const int& cy = y;
func(const_cast<int*>(&cy)); // ✅ 安全,原始对象非 const
🔹4. reinterpret_cast<>
✅ 用于:
- 最底层的强制类型转换;
- 位级别重新解释对象的内存;
- 指针类型之间的转换、函数指针类型转换等;
int ↔ pointer
等非常规转换。
🚫 非常危险:
- 不做类型检查、不保证可移植性;
- 适用于需要操作裸内存、底层驱动、协议实现等;
- 几乎永远不应该用于普通 C++ 代码,除非你知道你在干什么。
🧠 示例:
int i = 65;
char* p = reinterpret_cast<char*>(&i); // 将 int 地址解释为 char 指针
std::cout << *p << std::endl; // 输出 'A',ASCII 65
uintptr_t addr = reinterpret_cast<uintptr_t>(p); // 指针转整数
🔍 四种转换方式对比表:
转换类型 | 功能 | 安全性 | 常见用途 |
---|---|---|---|
static_cast |
编译期安全转换 | ✅ 高 | 基类<->派生类、基本类型、用户自定义转换 |
dynamic_cast |
运行期检查的安全向下转型 | ✅ 非常高 | 多态类之间指针/引用的转换 |
const_cast |
去除 const 或 volatile |
⚠️ 低 | 调用旧函数、修改 mutable 变量等 |
reinterpret_cast |
位级重新解释类型 | ❌ 非常低 | 指针之间转换、内存操作、底层驱动/协议实现 |
🧠 总结建议:
- 用
static_cast
来进行 已知安全的类型转换。 - 用
dynamic_cast
来进行 不确定但可检查的类型转换(比如基类转派生类)。 - 用
const_cast
只在你确实知道原始对象非 const 且你必须修改它时。 - 用
reinterpret_cast
只在特别底层的程序中,且你非常清楚风险和目标。
仅供参考!