必须用 static_cast 而不是 C 风格转换,因为它在编译期拒绝不安全转换(如 void*→int),而 C 风格会静默跳过类型检查;数值转换、向上转型、用户定义转换均应优先使用 static_cast。

什么时候必须用 static_cast 而不是 C 风格转换
因为 C 风格转换((int)x)会静默跳过类型安全检查,而 static_cast 在编译期就拒绝不合理的转换,比如把 void* 直接转成 int 会报错,但 C 风格不会。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 数值类型之间转换(
double→int、long→short)优先用static_cast,它明确表达“我清楚这是截断/精度损失” - 类层次中向上转型(子类指针 → 父类指针)安全且推荐,编译器不检查运行时类型,所以不能用于向下转型
- 避免在有用户定义转换函数的类之间用 C 风格,
static_cast会按预期调用operator int()等,C 风格可能绕过或行为不一致
dynamic_cast 为什么只对多态类型有效
因为 dynamic_cast 依赖 RTTI(运行时类型信息),而 RTTI 只在至少有一个虚函数的类中才被编译器生成。没有虚函数的类,dynamic_cast 编译直接失败,错误信息是 error: cannot dynamic_cast ... (source type is not polymorphic)。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 向下转型(父类指针 → 子类指针)必须用
dynamic_cast,且目标类要有虚函数(哪怕只有virtual ~Base() = default;) - 转型失败时返回空指针(指针场景)或抛出
std::bad_cast(引用场景),务必检查返回值,否则解引用空指针就是未定义行为 - 性能敏感路径(如游戏循环内)慎用,RTTI 查表有开销;非必要别在 hot path 上做
dynamic_cast
const_cast 的唯一正当用途是什么
仅当调用一个**本不该修改但没加 const 声明的旧 C API** 时才用。比如某 C 函数签名为 void legacy_func(char* buf),而你手头只有 const std::string& s,且你能 100% 确保该函数内部绝不会写入内存 —— 此时才考虑 const_cast。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 绝对不要用
const_cast去修改真正 const 的对象(如const int x = 42;),结果是未定义行为 - 现代 C++ 中,99% 的 const 问题源于接口设计缺陷,优先改调用方逻辑或封装一层适配,而不是硬 cast
- 代码审查时看到
const_cast,第一反应应是“这里是不是本该用std::string_view或重载?”
reinterpret_cast 为什么是最危险的转换
它直接把一块内存的二进制解释方式强行重定义,编译器不做任何语义校验。比如把 int* 强转成 double* 再解引用,结果取决于平台字节序和对齐,完全不可移植。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 只在极少数系统编程场景下使用:实现
memcpy替代、与硬件寄存器交互、序列化/反序列化时绕过 strict aliasing 规则(需配合std::memcpy更安全) - 禁止用于类类型之间的转换(哪怕布局相同),不同编译器对虚表、内存填充的处理可能不同
- 一旦用了
reinterpret_cast,必须加详细注释说明:原始类型、目标类型、为何必须这么做、是否已验证对齐和生命周期
四个 cast 各有边界,越界使用的代价不是编译失败,而是运行时随机崩溃或数据错乱——尤其在开启优化(-O2)后,编译器可能基于“你不会干傻事”的假设做激进推导,让 bug 更难定位。







