C语言存在隐式类型转换,让我们在不知情的情况下,发生类型转换,如double转换为int会发生隐式类型转换,这样会导致精度丢失。这种情况下我们无法进行错误检查。
C++为了加强类型转换的可视性,即让人一眼就知道哪里发生了类型转换,引入了四种强制类型转换操作符。
目录
1、static_cast
static_cast 用于同族类型转换,无法让两个不相关的类型转换。(编译器隐式执行的任何类型转换都可用static_cast)
比如double 和 int都属于整型家族,就可以使用static_cast操作符
double a = 10.11;
int b = static_cast<int>(a); // 将变量a转换成int类型,然后赋值给b
2、 reinterpret_cast
reinterpret_cast 用于毫无关系的类型转换。
typedef void (*Test)();
void Func() {
cout << "Func()" << endl;
}
int main() {
Test test = reinterpret_cast<Test>(Func); // 将Func类型的函数指针转换成Test类型
test();
return 0;
}
注意:虽然可以实现不同类型的转,但是不允许父类对象和子类对象的强制转换
3、const_cast
const_cast 可以取消常性,即删除变量的const属性。
具体使用详见:const_cast取消const属性及其注意事项
4、dynamic_cast(多态类型转换)
dynamic_cast 用于将一个 父类对象的指针/引用 转换 为子类对象的指针或引用。子类对象指针可以直接赋值给父类对象,但是父类对象无法赋给子类对象,dynamic_cast解决了这个问题。
- 向上转型:子类对象指针/引用 =》父类对象指针/引用(天然兼容,无需转换)
- 向下转型:父类对象指针/引用 =》子类对象指针/引用(使用dynamic_cast转换)
转换所需条件:父类必须包含虚函数
转换结果:若需要转换,返回转换以后的指针;如果无需转换,返回nullptr
转换过程:在转换之前会先检查转入的指针或者引用指向了什么
- func(&f):传入父类指针,Father* pf 指向的是一个Father类型的对象,类型相同,无需转换
- func(&s):传入子类指针,Father* pf 指向的是一个Son类型的对象,类型不同,需要将pf转换成Son类对象。
class Father {
virtual void buy_ticket() {}
};
class Son: public Father
{
};
void func(Father* pf)
{
Son* ps = dynamic_cast<Son*>(pf);
cout << ps << endl;
}
int main() {
Father f;
Son s;
func(&f);
func(&s);
return 0;
}
注意:使用static_cast 也可以对其进行转换
- 如果pf 指向一个父类对象,此时不做任何处理,直接返回父类对象的指针;
- 如果pf指向一个子类对象,此时会转换成子类对象,并返回子类对象指针。