C语言的类型转换
在C语言中,如果赋值运算符左右两侧的类型,形参与实参的类型,函数返回值的类型与接收值的类型不同,就需要发生类型转换。C语言存在两种类型转换:隐式类型转换和显式类型转换
缺陷:
C++ 为了增强类型转换的可视性,引入了 4 种强制类型转换的操作符
static_castreinterpret_castconst_castdynamic_castC++ 兼容C语言的强制类型转换,但还是希望大家使用新的强制类型转换操作符,以此来提高规范性,可读性,降低出错率。
static_cast 用于非多态类型的转换(静态转换),编译器隐式执行的任何类型都可以用 static_cast ,但它不能用于两个不相关的类型之间的转换。
double d = 10.24;
int a = static_cast<int>(d);
cout << a << endl; //10
reinterpret_cast 可以用于两个不相近的类型之间的转换
比如用指针转int类型,只能用 reinterpret_cast ,用 static_cast 会报错。
int* p = &a;
//int x = static_cast(p); // 报错:E0171 类型转换无效
int x = reinterpret_cast<int>(p);
cout << x << endl;
用于去除变量的 const 属性,方便赋值
如以下情景,不能使用reinterpret_cast
const int ca = 2;
//int* pi = reinterpret_cast(&ca); //报错 E0694 reinterpret_cast 无法丢掉常量或其他类型限定符
int* pi = const_cast<int*>(&ca);
*pi = 3;
cout << ca << endl;
cout << *pi << endl;
这里就有个小问题了,结果是什么?
如果你希望编译器去内存中取 const 变量,可以在前面加 volatile,此时的结果就是 3 3 了。
volatile const int ca = 2;
reinterpret_cast规范向下转换,转换是安全的
对象是天然支持向上转换的(切片),但是不支持向下转换。
注意:
dynamic_cast 只能用于父类含有虚函数的类dynamic_cast 会先检查是否能转换成功,能成功则转换,不能则返回 0利用它我们可以检查一个父类指针是指向子类对象还是父类对象:
class A
{
public:
virtual void f() {} // 父类必须有虚函数才能用dynamic_cast
};
class B : public A
{};
void fun(A* pa)
{
if (dynamic_cast<B*>(pa))
{
cout << "转换成功" << endl;
}
else
{
cout << "转换失败" << pa << endl;
}
}
void test2()
{
A a;
B b;
fun(&a);
fun(&b);
}
//转换失败0093FC38
//转换成功
dynamic_cast ,更加安全。