1. static_cast ------ 最常用的"本分"转换
什么时候用?
基本类型之间转换(int ↔ double,char ↔ int)
父子类指针/引用之间的向上转型(子类 → 父类,绝对安全)
父子类指针/引用之间的向下转型(父类 → 子类,不安全,但语法允许)
任何"有明确定义"的类型转换,比如 void* → 具体类型*
特点:
编译时检查(不检查运行时类型)
不做安全保证,你自己要确保转换合理
例子:
cpp
double d = 3.14;
int i = static_cast<int>(d); // 3,可以
class Base {};
class Derived : public Base {};
Derived d;
Base* b = static_cast<Base*>(&d); // ✅ 向上转型,安全
Base* b2 = new Base;
Derived* d2 = static_cast<Derived*>(b2); // ⚠️ 编译通过,但危险!b2实际不是Derived
2. dynamic_cast ------ 安全的"多态"转换
什么时候用?
把父类指针/引用转成子类指针/引用(向下转型),并且你需要知道转换是否成功
前提: 父类至少有一个虚函数(多态类型)
特点:
运行时检查类型
转换失败:指针 → nullptr,引用 → 抛出 std::bad_cast
比 static_cast 慢一点点,但安全
例子:
cpp
class Animal { virtual void speak(){} }; // 有虚函数
class Dog : public Animal {};
Animal* a = new Dog;
Dog* d = dynamic_cast<Dog*>(a); // ✅ 成功,d不为空
Animal* a2 = new Animal;
Dog* d2 = dynamic_cast<Dog*>(a2); // ❌ 失败,d2 == nullptr
3. reinterpret_cast ------ 危险的"瞎转"
什么时候用?
完全不相干的类型之间的转换,比如 int* ↔ double*
指针 ↔ 整数(底层位模式重解释)
几乎只在底层编程、序列化、硬件访问时使用
特点:
编译时直接重解释比特位,不做任何检查
几乎不保证可移植性
能用别的就别用它
例子:
cpp
int x = 65;
int* p = &x;
char* c = reinterpret_cast<char*>(p); // 把int*当char*用,危险
std::cout << *c; // 可能输出 'A'(小端机器),但非常容易出错
4. const_cast ------ 去掉 const 的"后悔药"
什么时候用?
需要一个"只在这个函数里"修改原本不是 const 的对象(比如函数参数是 const,但你知道它本来不是 const)
调用一个非 const 成员函数,但你手里只有 const 引用
特点:
只能添加或移除 const/volatile
绝对不能用来修改一个原本就是 const 的对象(后果是未定义行为)
例子:
cpp
void print(char* p) { std::cout << p; }
const char* msg = "hello";
// print(msg); // 错误,不能传const char*给char*
print(const_cast<char*>(msg)); // 去掉const,但msg本身是const char*,修改它会导致未定义行为
⚠️ 除非你100%确认原对象不是 const,否则不要用 const_cast 去修改内容。
一句话总结

实际开发建议
大部分情况 static_cast 够用
多态向下转型时,优先用 dynamic_cast
尽量避免 reinterpret_cast 和 const_cast,它们往往是代码设计有问题的信号
C 风格转换 (int)x 在 C++ 中不推荐,因为它实际上就是 reinterpret_cast + const_cast 的混合体,容易被误用