前言
当赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化。
C语言中的类型转换形式:隐式类型转换和显示类型转换。
C语言风格的类型转换格式简单,但可能造成数据精度的丢失以及代码不够清晰等问题,并且转换的可视性比较差。
一:C++强制类型转换
为了弥补C语言的缺陷,C++提出了自己的类型转化风格,由于C++要兼容C语言,所以C++中还可以使用C语言的转化风格。
C++引入了四种命名的强制类型转换操作符:static_cast、reinterpret_cast、const_cast、dynamic_cast。
1.1 static_cast
static_cast用于相关类型间的转换(静态转换)
编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换。
代码演示:
int main(){
double d = 12.34;
int a = static_cast<int>(d);
cout << a << endl;
return 0;
}
1.2 reinterpret_cast
reinterpret_cast用于不相关类型间的转换
显示类型转换(类型强转)都可用reinterpret_cast,但它不能用于两个相关的类型进行转换。
代码演示:
int main(){
int a = 10;
int* b = reinterpret_cast<int*>(a);
cout << b << endl;
return 0;
}
1.3 const_cast
const_cast最常用的属性是删除变量的const属性,方便赋值。
代码演示:
int main(){
const int a = 2;
int* p = const_cast<int*>(&a );
cout << a << endl;
return 0;
}
1.4 dynamic_cast
dynamic_cast用于将一个父类对象的指针或引用转换为子类对象的指针或引用(动态转换)
- dynamic_cast只能用于含有虚函数的类。
- dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0。
向上转换: C++中子类对象的指针或引用赋值给父类对象的指针或引用,转换过程会发生切片,语法天然支持。
向下转换: C++中父类对象的指针或引用赋值给子类对象的指针或引用,用dynamic_cast转型是安全的。
代码演示:
class A{
public :
virtual void f(){}
};
class B : public A
{};
void fun (A* pa){
// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回
B* pb1 = static_cast<B*>(pa);
B* pb2 = dynamic_cast<B*>(pa);
cout<<"pb1:" <<pb1<< endl;
cout<<"pb2:" <<pb2<< endl;
}
int main (){
A a;
B b;
fun(&a);
fun(&b);
return 0;
}
dynamic_cast的原理: dynamic_cast通过到被指向对象的虚表上方找到标识对象的信息,检查是否能够转换成功。
小结
强制类型转换关闭或挂起了正常的类型检查,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。强烈建议:避免使用强制类型转换。