static_cast
- 这种类型的转换会在编译时进行类型检查
- 用于基础数据类型之间的转换,如把int转换成char,把char转换成int,这种转换的安全性需要开发人员来保证。
- 用于层次结构中父类和子类之间指针或者引用的转换。
- 向上转换:把子类的指针或引用转换成父类表示,是安全的转换。
- 向下转换:把父类的指针或引用转换成子类表示,由于没有动态类型检查,所以是不安全的。
- 不能将两个没有任何关系的指针类型进行强制类型转换
语法:static_cast<目标类型>(原始对象)
class Base {};
class Child :public Base{};
void test() {
double a = 3.57;
int b = static_cast<int>(a);
std::cout << b << std::endl;
Base *base = nullptr;
Child *child = nullptr;
Base *base2 = static_cast<Base *>(child);//向上转换,安全
/*
可以转换完成,但使用child2是否安全得不到保证,向下转换应该使用dynamic_cast
*/
Child *child2 = static_cast<Child *>(base);//向下转换,不安全
Other *other = static_cast<Other *>(child);//编译失败,转换必须是父子之间。
int val = 7;
int* valPtr = &val;
char *charValptr = static_cast<char *>(valPtr);//编译失败,两个指针类型独立,无法强制转换
}
dynamic_cast
语法:dynamic_cast<目标类型>(原始对象)
- 主要用于父类与子类之间向上转换和向下转换, 向下转换时必须要有虚函数重写;
- 类层次之间向上转换时,dynamic_cast和static_cast的效果是一样的。
- 在进行下行转换时,dynamic_cast具有类型检查功能,比static_cast更安全。
- 不可以对基础数据类型进行转换。
- dynamic_cast非常的严格,失去精度或不安全都不可以转换
- dynamic_cast子类和父类之间发生了多态,即必须要有虚函数重写,则可以让父类转换成子类。向下转换。
class Base {
virtual void func() = 0;
};
class Derived : public Base {
void func() override {}
};
int main() {
Base *basePtr = new Derived();
Derived *derivedPtr = dynamic_cast<Derived *>(basePtr);
if (derivedPtr != nullptr) {
//转换成功,可以安全的使用
} else {
//转换失败,basePtr并不指向一个Derived对象
}
}
const_cast
该运算符用来修改类型的const属性。
- 常量指针被转换成非常量指针,并且仍然指向原来的对象
- 常量引用被转换成非常量引用,并且仍然指向原来的对象
注意不能对非指针或者非引用的变量使用const_cast操作符去直接移除它的const
const int a = 10;
const int *p = &a;
int *p2 = p;//编译错误
int *p3 = const_cast<int *>(p); //去除const属性
const int *p4 = const_cast<const int *>(p3); //加上const属性
const int &refa = a;
int &refa2 = refa;//编译错误
int &refa3 = const_cast<int &>(refa); //除去const属性
const int &refa4 = const_cast<const int &>(refa3); //加上const属性
int a2 = const_cast<int>(a);//编译错误,不能对非指针或者引用进行操作
const int val = 5;
int &valRef= const_cast<int &>(val); //通过
reinterpret_cast
这是一种最不安全的转换机制,最有可能出现问题,将数据从一种类型重新解释为另一种类型,它可以将一个指针转换成一个整数,也可以将一个整数转换成一个指针。
int a = 3;
//int *p = a; //编译错误
int *p = reinterpret_cast<int *>(a);
int *p2 = nullptr;
//int b = p2;//编译错误
int b = reinterpret_cast<int>(p2);
Base *base = nullptr;
Other *other = nullptr;
other = reinterpret_cast<Other *>(base);