C++ 中的显式类型转换
| cast 类型 | 用途 | 安全性 | 常用程度 | 学起来一句话总结 |
|---|---|---|---|---|
static_cast | 编译期安全转换 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 能编译过的正常类型转换基本用它 |
reinterpret_cast | 位级别重解释 |
C++ 中四种显式类型转换操作符:static_cast、reinterpret_cast、const_cast 和 dynamic_cast。static_cast 适用于编译期安全转换,如基本类型转换和继承向上转型;reinterpret_cast 用于位级别重解释,无安全检查且易导致未定义行为;const_cast 专门用于移除或添加 const/volatile 属性;dynamic_cast 用于多态类型的运行时安全向下转型。文章通过示例代码对比了它们的用途、安全性及适用场景,强调在满足需求时应优先使用安全的转换方式以避免未定义行为。
| cast 类型 | 用途 | 安全性 | 常用程度 | 学起来一句话总结 |
|---|---|---|---|---|
static_cast | 编译期安全转换 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 能编译过的正常类型转换基本用它 |
reinterpret_cast | 位级别重解释 |
| ⭐ |
| ⭐ |
| 允许你'把东西当成另一种东西看' |
const_cast | 去掉 / 添加 const | ⭐⭐⭐ | ⭐⭐⭐ | 唯一可以丢掉 const 的 cast |
dynamic_cast | 运行时检查 RTTI 的安全向下转型 | ⭐⭐⭐⭐⭐ | ⭐⭐ | 专为多态类型设计 |
double d = static_cast<double>(5); // OK
Parent* p = static_cast<Parent*>(child_ptr); // 向上转换安全
void* vp = &d;
double* dp = static_cast<double*>(vp); // OK,static_cast 可用于 void*
❌ 错误示例(会编译失败)
int* ip = static_cast<int*>(some_double_ptr); // 不允许,不安全
一句话总结:
能用
static_cast的地方,就不用别的 cast,它最'正统'。
int i = 0x11223344;
char* p = reinterpret_cast<char*>(&i); // 获取字节级别内容
long addr = reinterpret_cast<long>(p); // 指针 <-> 整数
❌ 错误风险
double* dp = reinterpret_cast<double*>(p);
double x = *dp; // 未定义行为!因为内存不是 double 布局
一句话总结:
reinterpret_cast是'霸王硬上弓',能做任何转换,但你必须保证安全性。
void f(const int* p) {
int* q = const_cast<int*>(p);
*q = 10; // ⚠ 若 p 原本指向的是 const 对象,UB!
}
所以 const_cast 只有一个真正安全的用途:
当你知道对象原本不是 const,只是接口要求参数是 const 时。
比如 API:
void foo(const int* x) {
int* p = const_cast<int*>(x); // 只要你保证 x 指向的不是 const 对象
}
一句话总结:
const_cast专门用来处理'去 const'的场景,不做类型转换。
✔ 向下转型(Parent → Child)
Parent* p = new Child();
Child* c = dynamic_cast<Child*>(p); // OK
✔ 失败时会返回 nullptr(指针版本)
Parent* p = new Parent();
Child* c = dynamic_cast<Child*>(p); // c == nullptr,安全!
✔ 引用版本失败会抛异常
Parent p;
Child& c = dynamic_cast<Child&>(p); // throws std::bad_cast
一句话总结:
dynamic_cast是唯一'真正安全'的向下转型方式,用于多态。
例如:
int i = 42;
double d = static_cast<double>(i); // d == 42.0
这里:
再比如:
Derived* d;
Base* b = static_cast<Base*>(d);
这里:
static_cast 永远不会破坏对象布局,是安全的语义转换。
想象你拿一本书(内存):
int x = 0x11223344;
char* p = reinterpret_cast<char*>(&x);
内存布局:
44 33 22 11 (在小端序机器上)
你只是 用 char 的方式读它的内容,而不是把 int 转成 char。
再看危险例子:
int* ip = new int(10);
double* dp = reinterpret_cast<double*>(ip);
double d = *dp; // ❌ 未定义行为
原因:
内存原样不动,只改变你访问它时使用的类型。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online