C++四种类型转换:static_cast、 dynamic_cast const cast、 reinterpret_cast

转换类型 语法 主要用途 安全性
static_cast static_cast(expr) 基本类型转换、父子类指针 / 引用转换(不检查动态类型) 相对安全
dynamic_cast dynamic_cast(expr) 安全的向下转型(运行时类型检查)、交叉转型 最安全
const_cast const_cast(expr) 移除或添加 const/volatile 限定符 需谨慎使用
reinterpret_cast reinterpret_cast(expr) 任意类型指针 / 引用转换、指针与整数互转(强制重新解释内存) 最不安全

详细描述与示例

1. static_cast

详解:

用于基本类型转换 (如 int 转 double)。

用于父子类之间的指针 / 引用转换(但不进行运行时类型检查,可能导致未定义行为)。

可用于显式调用隐式转换(如构造函数或类型转换运算符)。

示例:

cpp 复制代码
// 基本类型转换
int num = 10;
double d = static_cast<double>(num);  // int → double

// 父子类转换(可能不安全)
class Base {};
class Derived : public Base {};

Derived* derived = new Derived();
Base* base = static_cast<Base*>(derived);  // 向上转型(安全)

Base* basePtr = new Base();
Derived* derivedPtr = static_cast<Derived*>(basePtr);  // 向下转型(不安全)

注意事项:

不检查动态类型,向下转型时若对象实际类型不匹配会导致未定义行为。

不能移除 const/volatile 限定符。

2. dynamic_cast

详解:

主要用于安全的向下转型 (从基类指针 / 引用转为派生类指针 / 引用)。

运行时检查类型(需虚函数表支持,因此基类必须至少有一个虚函数)。

若转换失败:

指针返回 nullptr。

引用抛出 std::bad_cast 异常。

示例:

cpp 复制代码
class Base { virtual void func() {} };  // 必须有虚函数
class Derived : public Base {};

Base* base = new Derived();
Derived* derived = dynamic_cast<Derived*>(base);  // 成功,返回有效指针

Base* basePtr = new Base();
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);  // 失败,返回 nullptr

// 引用转换示例
Base& baseRef = *basePtr;
try {
    Derived& derivedRef = dynamic_cast<Derived&>(baseRef);  // 抛出 std::bad_cast
} catch (const std::bad_cast& e) {
    std::cerr << e.what() << std::endl;
}

注意事项:

仅适用于多态类型(含虚函数的类)。

性能开销高于 static_cast,因为需要运行时类型信息(RTTI)。

3. const_cast

详解:

唯一能移除或添加 const/volatile 限定符 的转换。

主要用于修改通过 const 指针 / 引用传递的对象(需确保原对象非 const)。

示例:

cpp 复制代码
// 移除 const(危险!)
const int* constPtr = new int(10);
int* nonConstPtr = const_cast<int*>(constPtr);
*nonConstPtr = 20;  // 若原对象非 const,则安全;否则行为未定义

// 添加 const
int x = 5;
int* ptr = &x;
const int* constPtr2 = const_cast<const int*>(ptr);  // *constPtr2 不可修改

注意事项:

若对真正的 const 对象使用 const_cast 并修改,会导致未定义行为。

仅用于指针或引用,不可用于值类型。

4. reinterpret_cast

详解:

执行最底层的强制类型转换 (如指针转整数、不同类型指针互转)。

不进行任何类型检查,完全依赖程序员确保安全性。

可能导致不可移植的代码(如不同平台指针大小不同)。

示例:

cpp 复制代码
// 指针转整数
int* ptr = new int(42);
uintptr_t intValue = reinterpret_cast<uintptr_t>(ptr);  // 指针转整数

// 不同类型指针互转(极其危险)
double d = 3.14;
double* dPtr = &d;
int* iPtr = reinterpret_cast<int*>(dPtr);  // 直接重新解释内存

// 函数指针转换(平台依赖)
void (*funcPtr)() = nullptr;
int (*intFuncPtr)(int) = reinterpret_cast<int(*)(int)>(funcPtr);

注意事项:

几乎所有 reinterpret_cast 的使用都是危险的,应尽量避免。

常用于底层编程(如系统调用、驱动开发)。

总结

转换类型 适用场景 安全性建议
static_cast 基本类型转换、明确的继承关系转换 谨慎使用向下转型
dynamic_cast 安全的多态类型转换 优先使用(需虚函数支持)
const_cast 临时移除 const 限定符 仅用于合法的非 const 对象
reinterpret_cast 底层系统编程 尽量避免,仅作为最后手段
相关推荐
小小龙学IT2 小时前
Boost.Interprocess 开源 C++ 进程间通信库深度解析
c++·开源
倒头就睡的小比特5 天前
算法竞赛C++常用的STL
c++·算法
weilx12345 天前
C++笔记-文件IO-<fcntl.h>
c++
Smileyqp沛沛6 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车6 天前
C/C++ 为什么需要编译器?
开发语言·c++
旖旎夜光6 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
吞下星星的少年·-·6 天前
C++ 萌新语法入门篇
c++·算法比赛
霍霍的袁6 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
another heaven6 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
程序猿编码6 天前
告别改源码适配模型:纯 C++ 可配置 LLM 推理引擎,全格式全结构兼容
c++·大模型·llm·推理引擎