1.
static_cast
用途:
- 在相关类型之间进行转换,例如基本数据类型之间的转换(如
int
转double
)。- 在类层次结构中进行指针或引用的上行转换(将派生类指针转换为基类指针)。
特点:
- 编译时类型检查,确保转换的安全性。
- 不会移除
const
或volatile
修饰符。- 不能用于完全不相关的类型之间的转换。
#include <iostream>
using namespace std;
class Base {
public:virtual void display() { std::cout << "Base" << std::endl; }
};class Dervied :public Base {
public:void display() override { std::cout << "Dervied" << std::endl; }
};int main() {double d = 3.14;int i = static_cast<int>(d);cout << "i: " << i << endl;Dervied dervied;Base* basePtr = static_cast<Base*>(&dervied); // 派生类指针转基类指针basePtr->display();// 输出: Derivedreturn 0;
}
2.
const_cast
用途:
- 修改对象的
const
或volatile
属性,主要用于去除或添加这些限定符。特点:
- 只能用于修改
const
或volatile
修饰符。- 不改变指针或引用所指对象的实际类型。
- 不能用于执行其他类型的转换。
#include <iostream>void printValue(const int* ptr) {//尝试修改值,需要去除constint* modPtr = const_cast<int*>(ptr);*modPtr = 20;std::cout << "*modPtr: " << *modPtr << std::endl;
}int main() {const int num = 10;std::cout << "Before: " << num << std::endl;printValue(&num);std::cout << "After: " << num << std::endl;return 0;}
3.
reinterpret_cast
用途:
- 执行低级的、几乎不受限制的类型转换,常用于将指针转换为整数或不同类型的指针之间的转换。
特点:
- 不保证类型安全,可能导致未定义行为。
- 常用于系统级编程或需要特定内存布局的场景。
- 应谨慎使用,避免错误。
#include <iostream>int main() {int x = 10;// 将指针转换为整数long ptrValue = reinterpret_cast<long>(&x);std::cout << "Pointer as long: " << ptrValue << std::endl;// 将整数转换为指针int* ptr = reinterpret_cast<int*>(ptrValue);std::cout << "Pointer value: " << *ptr << std::endl; // 输出: 10return 0;
}
4.
dynamic_cast
用途:
- 在类层次结构中进行安全的向下转换(将基类指针或引用转换为派生类指针或引用)。
- 支持运行时类型检查,确保转换的安全性。
特点:
- 只能用于有虚函数的类(即需要支持运行时类型识别的类)。
- 需要运行时类型信息(RTTI)的支持。
- 如果转换失败,对于指针类型返回
nullptr
,对于引用类型会抛出std::bad_cast
异常。
#include <iostream>
#include <typeinfo>class Base {
public:virtual void display() {std::cout << "base" << std::endl;}
};class Small :public Base {
public:void display() override {std::cout << "small" << std::endl;}void mysmall() {std::cout << "my small" << std::endl;}
};int main() {Base* basePtr = new Small();
//尝试将基类指针转换为派生类指针Small* smallPtr = dynamic_cast<Small*>(basePtr);if (smallPtr) {smallPtr->mysmall();}}