static_cast是编译期零开销显式转换,适用于基本类型、有转换函数的类、void*互转及上行转换;dynamic_cast依赖RTTI和虚函数,仅用于多态类型的安全向下或跨继承转换,失败时返回nullptr或抛异常。

static_cast 是编译期检查的显式类型转换,不带运行时类型验证;dynamic_cast 专用于多态类型间的安全向下转型或跨继承关系转换,依赖 RTTI(运行时类型信息),只对含虚函数的类有效,失败时返回空指针(指针)或抛出异常(引用)。
适用场景不同
static_cast 可用于:基本类型间转换(如 int → double)、有明确定义转换函数或构造函数的类类型转换、void* 与具体指针类型互转、上行转换(派生类指针→基类指针)等。它不检查对象实际类型,信任程序员判断。
- int i = 10; double d = static_cast
(i); // 合法 - Base* b = static_cast
(derived_ptr); // 上行转换,总是安全 - void* p = &x; int* ip = static_cast
(p); // 合法但需确保语义正确
是否依赖 RTTI 和虚函数
dynamic_cast 必须在多态类型(即至少有一个虚函数的类)中使用,且编译时需开启 RTTI(大多数编译器默认开启)。若用于非多态类型,编译直接报错。
- class Base { virtual ~Base() = default; }; class Derived : public Base {}; // 多态,可 dynamic_cast
- class Plain { }; Plain p; Base* b = &p; dynamic_cast
(b); // 编译错误:Plain 非多态
安全性与失败处理机制
static_cast 不做运行时校验,错误转换可能导致未定义行为(如把 Base* 强转为无关 Derived* 后调用虚函数);dynamic_cast 在下行转换失败时会安全返回 nullptr(指针)或抛出 std::bad_cast(引用),便于显式处理错误。
立即学习“C++免费学习笔记(深入)”;
- Base* b = new Base; Derived* d = static_cast
(b); // 编译通过,运行时危险 - Derived* d2 = dynamic_cast
(b); // 返回 nullptr,可判断 if (d2) { ... } - try { Derived& ref = dynamic_cast
(*b); } catch (const std::bad_cast&) { /* 处理错误 */ }
性能与开销
static_cast 是零开销转换,全部在编译期完成;dynamic_cast 需要查询虚表和类型信息,有运行时开销,尤其在复杂继承体系中可能较慢。因此,在明确安全的前提下优先用 static_cast。
- 上行转换、已知类型关系、非多态场景 —— 用 static_cast
- 不确定子类类型、需安全向下转型、涉及多态 —— 用 dynamic_cast
- 避免用 reinterpret_cast 或 C 风格转换替代二者,它们更不安全










