static_cast(静态转换)
static_cast 是 C++
提供的编译时类型转换,它在编译时进行类型检查,适用于一些相对明确和安全的转换,但程序员仍需对某些转换(如下向转型)的运行时安全性负责,case
3 例子说明向下类型转换不要使用 static_cast
。
case 1: 基本数据类型转换
1 | double d = 3.14; |
case 2: 基类与派生类的向上转换
1 | class Base { |
如果我们有一个指向派生类的指针,我们可以使用 static_cast
将其转换为指向基类的指针。像这样的向上类型转换,完全没有问题。
1 | Derived derived(10); |
case 3: 基类与派生类的向下转换(错误示范 ❌)
如果我们有一个指向基类的指针,我们不能使用 static_cast
将其转换为指向派生类的指针,虽然这会通过编译,但会导致未定义行为。
1 | Base base(10); |
dynamic_cast(动态转换)
dynamic_cast
是 C++
提供的运行时类型转换,它会在运行时进行类型检查。主要用于基类和派生类之间的转换,尤其是安全的向下转换(Base
→ Derived)
case 4: 基类与派生类的向下转换(正确示范)
1 | class Base { |
下面的代码中,我们使用 dynamic_cast
将基类指针转换为派生类指针。如果转换成功,dynamic_cast
会返回一个指向派生类的指针,我们可以安全地调用派生类的成员函数。如果转换失败,dynamic_cast
会返回 nullptr
。
下面的代码类型转换会失败,输出
Failed to cast to Derived
。
1 | Base *base = new Base(); |
下面的代码类型转换会成功,输出
Hello from Derived
。
1 | // 本来就是 Derived 类型的指针,只是被 Base 指针指向了 |
注意:如果基类没有虚函数,则
dynamic_cast
无法执行正确的运行时检查,会导致未定义行为。
const_cast(去除 const/volatile 限定符)
case 5: 去除可变数据的 const 限定符
如果原始对象本身不是常量,则 const_cast
可以用于去除对象的 const
限定符。下面的例子比较古怪,一般不会这么写,它说明 str
原来是可变的,只是在传播途中被 const
修饰了。
1 | void modify(const char *str) { |
case 6: 去除常量数据的 const 限定符(错误用法 ❌)
如果原始对象本身是常量,则 const_cast
不能用于去除对象的 const
限定符,否则会导致未定义行为。
1 | int main() { |
reinterpret_cast
reinterpret_cast
用于底层的、与类型系统无关的位模式重新解释,风险最高,应谨慎使用。
case 7: 指针与整数之间的转换
1 | int a = 42; |
case 8: 将不同类型指针转换后误用(错误用法 ❌)
如果将一个类型的指针错误地转换为另一个类型的指针,若尝试访问,可能会破坏内存布局,导致未定义行为。
1 | int a = 10; |