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 底层系统编程 尽量避免,仅作为最后手段
相关推荐
XiaoyaoCarter9 分钟前
每日一道leetcode(新学数据结构版)
数据结构·c++·算法·leetcode·职场和发展·哈希算法·前缀树
八月的雨季 最後的冰吻35 分钟前
SIP协议栈--osip源码梳理
linux·服务器·网络·c++·网络协议
fancy1661661 小时前
搜索二维矩阵 II
c++·算法·矩阵
freyazzr1 小时前
Leetcode刷题 | Day63_图论08_拓扑排序
数据结构·c++·算法·leetcode·图论
顾子茵2 小时前
c++从入门到精通(四)--动态内存,模板与泛型编程
java·开发语言·c++
ai.Neo2 小时前
牛客网NC22015:最大值和最小值
数据结构·c++·算法
醍醐三叶3 小时前
C++核心编程--3 函数提高
c++
范纹杉想快点毕业4 小时前
以项目的方式学QT开发(一)——超详细讲解(120000多字详细讲解,涵盖qt大量知识)逐步更新!
c语言·数据结构·c++·git·qt·链表·github
敷啊敷衍5 小时前
深入探索 C++ 中的 string 类:从基础到实践
开发语言·数据结构·c++
什么名字都被用了5 小时前
编译openssl源码
c++·openssl