C++类型转换
1.c语言类型转换存在的问题
(1)隐式类型转换有些情况下可能会出现问题,比如数据精度的丢失;
(2)显式类型转换将所有类型混合到一起,可读性不高
(3) 很难在源码中快速定位到使用强转的语句;
2.c++的四种类型转换
(1) static_cast
用于内置的数据类型之间的转换,支持具有继承关系的指针或引用之间的转换
代码示例:
class B{
};
class C :public B{
private:
string _name;
};
void test()
{
float a = 12.34;
int b = static_cast<int>(a);
//父类的指针转换为子类指针
B* pb = new B;
C* pc = static_cast<C*>(pb);
//static_cast不支持强制类型转换
// error
a = static_cast<int>(pb);
}
(2)reinterpret_cast
可以认为是强制类型转换,但是是有限制的。
reinterpret_cast 用于进行各种不同类型的指针之间、不同类型的引用之间以及指针和能容纳指针的整数类型之间的转换。转换时,执行的是逐个比特复制的操作
代码示例:
typedef void(*FUN)();
void fun()
{}
struct Base{};
void test()
{
//不同类型的指针之间的转换
FUN f = reinterpret_cast<FUN>(fun);
int a = 10;
//指针和能容纳指针的整数类型之间的转换
int* p = reinterpret_cast<int*>(a);
Base obj;
//类型转换无效
//p = reinterpret_cast<int*>(obj);
//不同类型的引用之间的转换
int m = 1024;
Base& obj2 = reinterpret_cast<Base&>(m);
//指针和整数之间的转换
int* p2 = nullptr;
int n = reinterpret_cast<int>(p2);
//整数和非整数之间的转换:类型转换无效
double l = 1.1234;
//n = reinterpret_cast<int>(l);
//指针和非整数之间的转换: 类型转换无效
//p2 = reinterpret_cast<int*>(l);
}
(3)const_cast
去除变量的const属性,方便赋值,但是强制转换的目标类型必须是指针或引用
注意:
编译器会自动优化,所以要加volatile关键字防止编译器过度优化
代码示例1:
不加volatile关键字修饰:
加volatile关键字修饰:
代码示例2:
引用类型间、指针类型间的转换
(4)dynamic_cast
只用于多态场景的父类的指针/引用向子类的指针/引用的转换,会进行安全性检查
代码示例:
非多态转换失败:
多态转换成功:
dynamic_cast与static_cast之间的区别:
dynamic_cast会进行安全性检查,如果不安全则转换失败返回0,
而static_cast不会进行安全性检查;
代码示例:
class A{
public:
virtual void fun(){}
};
class B :public A{
};