C++具名转型的功能和用途
C++具名转型的功能和用途
- 1. static_cast
- 功能
- 用途
- 示例
- 2. dynamic_cast
- 功能
- 用途
- 示例
- 3. const_cast
- 功能
- 用途
- 示例
- 4. reinterpret_cast
- 功能
- 用途
- 示例
- 对比总结
- 最佳实践
在 C++ 中,具名转型(Named Casts) 是类型安全的显式类型转换操作符,相比传统的 C 风格强制转换,具名转型具有更明确的语义和编译器检查。C++ 提供四种标准具名转型:
1. static_cast
功能
- 用于编译时已知类型关系的转换
- 可执行基本类型转换、父子类指针/引用转换(无动态类型检查)
- 不能移除 const/volatile 限定符
用途
- 基本数值类型转换
- 类层次中的向上转换(子类→基类)
- 隐式转换的显式写法(如 void* → 其他指针)
示例
// 基本类型转换
double d = 3.14;
int i = static_cast<int>(d); // i = 3
// 类层次向上转换
class Base {};
class Derived : public Base {};
Derived* pd = new Derived;
Base* pb = static_cast<Base*>(pd); // 安全向上转换
// void* 转换
int x = 10;
void* pv = static_cast<void*>(&x);
int* pi = static_cast<int*>(pv);
2. dynamic_cast
功能
-
用于运行时类型检查的类层次转换(需要 RTTI 支持)
-
主要用于向下转换(基类→子类)
-
只能用于多态类型(基类必须有虚函数)
用途
-
安全地将基类指针/引用转换为派生类指针/引用
-
转换失败时返回 nullptr(指针)或抛出异常(引用)
示例
class Animal { public: virtual ~Animal() {} };
class Dog : public Animal { public: void bark() {} };
Animal* pa = new Dog;
// 向下转换(安全)
Dog* pd = dynamic_cast<Dog*>(pa);
if (pd) {
pd->bark(); // 转换成功
}
// 处理交叉转换(cross cast)
class Cat : public Animal {};
Animal* pa2 = new Cat;
Dog* pd2 = dynamic_cast<Dog*>(pa2); // 返回 nullptr
3. const_cast
功能
-
移除或添加 const/volatile 限定符
-
不能改变实际类型,只能改变访问权限
用途
-
修改第三方库中未正确声明为 const 的 API
-
临时去除 const 以兼容旧代码(需谨慎)
示例
// 合法使用:去除 const 访问非 const 对象
int value = 42;
const int* cp = &value;
int* p = const_cast<int*>(cp); // 合法
*p = 100; // 安全:原对象本身不是 const
// 危险操作:修改真正的 const 对象
const int ci = 50;
int* pci = const_cast<int*>(&ci);
*pci = 60; // 未定义行为(UB)
4. reinterpret_cast
功能
-
低级别的位模式重新解释
-
不进行任何类型检查或转换
-
可能导致未定义行为(UB)
用途
-
指针与整数之间的转换
-
不相关指针类型之间的转换(如 float* → int*)
示例
// 指针转整数(平台相关)
int x = 42;
uintptr_t addr = reinterpret_cast<uintptr_t>(&x);
// 不同类型指针转换
float f = 3.14f;
int* pi = reinterpret_cast<int*>(&f); // 重新解释二进制位
// 危险:函数指针转换
typedef void (*FuncPtr)();
FuncPtr fp = reinterpret_cast<FuncPtr>(&x); // 调用导致 UB
对比总结
转型操作符 | 使用场景 | 安全性 | 运行时开销 |
---|---|---|---|
static_cast | 明确的类型转换 | 编译时检查 | 无 |
dynamic_cast | 多态类层次的安全向下转换 | 运行时检查 | 有 |
const_cast | 修改 const/volatile 属性 | 需人工保证 | 无 |
r einterpret_cast | 低级二进制重新解释 极不安全 | 无 |
最佳实践
-
优先使用 static_cast,避免 C 风格强制转换
-
慎用 const_cast:确保原对象不是真正的常量
-
限制 reinterpret_cast:仅在硬件操作或系统编程时使用
-
用 dynamic_cast 替代向下转型:结合 if 检查结果
// 安全转型模板
template <typename To, typename From>
To safe_cast(From from) {
static_assert(std::is_polymorphic_v<From>, "Need polymorphic type");
To to = dynamic_cast<To>(from);
if (!to) throw std::bad_cast();
return to;
}