C++的强制类型转换

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 的混合体,容易被误用

相关推荐
lhbweilai14 分钟前
分析FreeRTOS内核对象API的源码实现(八)
c语言·开发语言·stm32·单片机
努力努力再努力wz18 分钟前
【C++高阶系列】C++20 协程底层原理:函数为什么能暂停?从状态机到 Task,彻底串起挂起、恢复与协程调度
开发语言·c++·c++20·1024程序员节
咩咩啃树皮30 分钟前
JavaScript 中 this 指向为什么总在变?
开发语言·前端·javascript
且随疾风前行.32 分钟前
Paint Cavans高级绘制:[一]Paint画笔高级应用
android·ui
程序员清风38 分钟前
算法题中的边界条件、测试与调试
开发语言·算法·kotlin
划破黑暗的第一缕曙光43 分钟前
[C++]:4.模板
c++·template·模板·函数模版·类模版
砚底藏山河44 分钟前
python量化实操:冷热分层存储
java·开发语言·python·金融
十五年专注C++开发1 小时前
pybind11:一个跨C++和Python平台的编程库
开发语言·c++·python·pybind11
CodeYp20191 小时前
第11讲:stack 和 queue
开发语言·c++·queue·stack
咩咩啃树皮1 小时前
JavaScript 异步流程为什么容易失控?从回调到可维护设计
开发语言·javascript·ecmascript