static_cast适用于编译期安全的类型转换,如隐式允许的数值转换、有继承关系的指针/引用上下行转换(下行不安全)、const修饰增删;但不可用于无关类型指针转换。

static_cast 适合什么场景
static_cast 是编译期检查的显式类型转换,不涉及运行时开销。它能完成编译器隐式允许的转换(比如 int → double),也能在有明确继承关系的指针/引用间做上行或下行转换,但不做安全性验证。
- 上行转换(子类→父类)安全,和隐式转换等价,
static_cast只是显式写出意图 - 下行转换(父类→子类)危险:编译器信你,但若实际对象不是目标子类,运行时行为未定义
- 不能用于无关类型指针转换(比如
void→int需用reinterpret_cast) - 对于 const 修饰,可加/去 const,但去 const 后修改原 const 对象仍是未定义行为
class Base {};
class Derived : public Base {};
Base* b = new Base;
Derived* d = static_cast(b); // 编译通过,但运行时解引用会崩溃
dynamic_cast 为什么必须带 RTTI
dynamic_cast 专用于多态类型的指针/引用下行转换,依赖运行时类型信息(RTTI),因此要求基类至少有一个虚函数(通常是虚析构函数)。它会在运行时检查对象真实类型,安全失败而非崩溃。
- 指针转换失败返回
nullptr,引用转换失败抛出std::bad_cast异常 - 若基类无虚函数,编译直接报错:
error: cannot dynamic_cast ... because Base has no virtual functions - 转换成本高于
static_cast:每次调用都要查虚表、比对类型信息 - 不支持内置类型转换(如
int→float),那是static_cast的事
class Base { virtual ~Base() = default; };
class Derived : public Base {};
Base* b = new Derived;
Derived* d = dynamic_cast(b); // 成功,d 指向有效对象
Base* b2 = new Base;
Derived* d2 = dynamic_cast(b2); // 失败,d2 == nullptr
什么时候该用 reinterpret_cast 或 const_cast
static_cast 和 dynamic_cast 都不覆盖所有转换需求,遇到以下情况得换别的 cast:
- 把任意指针转成
void*或反过来?用static_cast就够(前提是类型兼容) - 把
int强转成char做字节级操作?必须用reinterpret_cast,static_cast编译不过 - 想去掉
const修饰去写一个本就不该改的对象?const_cast是唯一合法方式,但后续写操作仍属未定义行为 -
dynamic_cast无法跨继承体系(比如从A转到完全无关的B),这种“暴力映射”只能靠reinterpret_cast,且极度危险
记住:能用 static_cast 的别用 reinterpret_cast;需要运行时校验的下行转换,别图省事用 static_cast 硬来。
立即学习“C++免费学习笔记(深入)”;
常见误用和调试线索
很多 segfault 或逻辑错误,根源是 cast 用错。遇到这类问题先盯住三件事:
- 检查下行转换是否用了
static_cast而不是dynamic_cast,尤其在工厂函数或容器存基类指针后取用时 - 看基类有没有虚函数:没有就用不了
dynamic_cast,加个虚析构是最小代价修复 -
dynamic_cast返回nullptr却没检查?这是空指针解引用的高发原因 - 把
dynamic_cast用在非多态类型上,编译器会直接拒绝,别硬改语法绕过
RTTI 在某些嵌入式或性能敏感环境会被关闭(如 GCC 的 -fno-rtti),此时 dynamic_cast 不可用,只能靠设计规避下行转换,或者自己维护类型标识字段。









