static_cast适用于编译器已知安全的转换:数值类型、有继承关系的指针/引用向上转型、explicit构造函数或operator T();向下转型、void*直转、const去除、无继承指针互转等会编译失败。
static_cast 什么时候能用,什么时候会编译失败
它只允许编译器已知的、安全的类型转换,比如数值类型之间(
→
)、有继承关系的指针/引用(向上转型),或者自定义类型中带
构造函数或
的情况。
常见错误现象:
(无继承关系的类指针互转)、
(C 风格指针转非 void* 类型,必须先转成中间类型如
)。
不能绕过 const 正确性:从
→
会失败,得用
不能把
直接转成任意具体类型指针,必须经由
或
中转
向下转型(基类指针 → 派生类指针)语法上允许,但不安全;运行时行为未定义,除非你 100% 确认对象真实类型
和 C 风格强制转换比,static_cast 多了什么检查
C 风格写法像
或
,本质是让编译器“闭嘴照做”,连基本类型兼容性都不拦——比如把
强转成
也能过编译,但很可能引发未定义行为。
把这类危险操作直接挡在编译期:
立即学习
“
C++免费学习笔记(深入)
”;
→ 编译失败(指针类型不相关)
→ 允许(数值转换)
→ 允许(void* 是唯一可被 static_cast 接受的源类型)
性能上没差别,都是零开销;区别全在编译期约束力。
C知道
CSDN推出的一款AI技术问答工具
下载
什么时候该换 dynamic_cast,而不是硬用 static_cast
当你需要向下转型(基类指针/引用 → 派生类),且不确定实际对象类型时,
就不该出现——它不会做运行时校验,出错就是崩溃或读垃圾内存。
典型场景:容器里存了一堆
,循环处理时想对其中某几个
做特殊操作。
用
,成功返回有效指针,失败返回
(指针)或抛
(引用)
要求基类至少有一个虚函数(通常是析构函数),否则编译报错:
有运行时开销(查虚表、type_info 比较),别在 hot path 上反复调用
容易被忽略的隐式转换干扰问题
有时候你以为自己在用
,其实编译器悄悄插了一步隐式转换,结果行为和预期不符。
例如:
看似想把整数转字符串,但
没有接受
的构造函数,也不会触发
—— 这行代码根本编译不过。真正要转字符串,得显式调用
。
自定义类型间转换必须明确定义转换构造函数或转换运算符,且不能是
(除非你主动加
)
枚举类(
)到整数必须用
,不能靠隐式转换
窄化转换(如
)在 C++17 后默认是合法的,但值会截断;若开启
(GCC/Clang),编译器会警告
最麻烦的是混合使用:有人写
,本意是取整再加一,但忘了
是向零截断,负数时和
行为不同——这种细节不看文档就容易翻车。
intdoubleexplicitoperator T()error: cannot cast from type 'A*' to type 'B*'error: invalid static_cast from type 'void*' to 'int*'char*const int*int*const_castvoid*char*unsigned char*(int)3.14(MyClass*)ptrfloat*int*static_caststatic_cast(float_ptr) static_cast(3.14f) static_cast(void_ptr) static_castBase*DerivedA*dynamic_cast(base_ptr) nullptrstd::bad_casterror: 'Base' is not polymorphicstatic_caststatic_cast<:string>(42)std::stringintstd::to_stringstd::to_string(42)explicitstatic_castenum classstatic_cast(my_enum) static_cast(256) -Wnarrowingstatic_cast(some_double) + 1 static_caststd::floor