转换类型 | 语法 | 主要用途 | 安全性 |
---|---|---|---|
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)。
用于父子类之间的指针 / 引用转换(但不进行运行时类型检查,可能导致未定义行为)。
可用于显式调用隐式转换(如构造函数或类型转换运算符)。
示例:
// 基本类型转换
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 异常。
示例:
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)。
示例:
// 移除 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
详解:
执行最底层的强制类型转换(如指针转整数、不同类型指针互转)。
不进行任何类型检查,完全依赖程序员确保安全性。
可能导致不可移植的代码(如不同平台指针大小不同)。
示例:
// 指针转整数
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 | 底层系统编程 | 尽量避免,仅作为最后手段 |