目录
C语言中的类型转换
C语言中又两种类型转换:(强制)显示类型转换和隐式类型转换。
(强制)显示类型转换:指针之间 整形和指针之间
隐式类型转换:整形之间 浮点数和整形之间
没有关联的类型不支持转换。
C++中的类型转换
C++兼容C语言,支持使用C语言的类型转换风格。
C++支持内置类型->自定义类型,同时也支持自定义类型->内置类型,也支持自定义类型->自定义类型:
class A
{
public:
A(int a)
:_a(a)
{
}
A(int a, int b)
:_a(a)
,_b(b)
{
}
operator int()
{
return _a + _b;
}
private:
int _a = 1;
int _b = 1;
};
int main()
{
//内置类型->自定义类型
A a1 = 2;
A a2 = { 5,9 };
//自定义类型->内置类型
int x = a1;
cout << x << endl;
//自定义类型->自定义类型,需要用构造函数支持
return 0;
}
C++强制类型转换
C语言的强制类型转换有些笼统,C++为了加强类型转换的可视性,引入四种强制类型转换操作符,对C语言的强制类型转换更清晰地划分。
static_cast、reinterpret_cast、const_cast、dynamic_cast
static_cast
用于隐式类型转换,类型之间比较接近的。
reinterpret_cast
用于强制类型转换。但是,C语言中之前不支持的强制转换现在依然不支持。
const_cast
const_cast用于删除变量的const属性,方便赋值。
我们先来看一个例子,const int a=1;a不是在常量区,而是在栈上,我们可以通过打印地址观察:
这种const修饰的变量叫常变量,只是在语法上不能修改。如果想修改它的值,也不是不可以:
我们发现,在内存中,x的值已经变了,但是打印出来的还是原来的值,这其实源自编译器的优化,编译器觉得,x是const修饰的,应该不会被改变,a直接先存到寄存器中,之后还是从寄存器中取,所以打印结果没有改变(VS下是编译时直接把x替换成1了)。这时,我们可以加关键字volatile,告诉编译器这个变量每次都去内存中去取。
从这个例子可以看出,把const属性去掉是很危险的,所以,C++单独用const_cast来支持。
dynamic_cast
dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用。
向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)
向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)
注意:1.dynamic_cast只能用于父类含有虚函数的类。
2.dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
class A
{
public:
virtual void f() {}
public:
int _a = 0;
};
class B : public A
{
public:
int _b = 0;
};
void func(A* pa)
{
//dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回
B* pb = dynamic_cast<B*>(pa);
if (pb)
{
cout << pb << "->转换成功"<< endl;
pb->_a++;
}
else
{
cout << "转换失败" << endl;
}
}
int main()
{
A a;
B b;
func(&a);
func(&b);
return 0;
}