本章草稿代码Gitee仓库:type_cast
0.前言
C语言的类型转换有2种:
- 隐式类型转换
- 显式类型转换
这里的类型转换并不是很规范,有时候会有潜在风险,例如下面这段代码:
void SubUnsigned(size_t pos)
{
int i = 10;
while (i >= pos)
{
cout << i << endl;
i--;
}
}
int main()
{
SubUnsigned(0);
return 0;
}
int i
整型被隐式类型转换成了size_t
无符号整型,这就导致当i=0
的时候,并不会减到负数,而是到了无符号整型的最大值
C++也兼容C的类型转换,但是C++将类型转换做出了规范,引入四种命名的类型转换操作符:static_cast
、reinterpret_cast
、const_cast
、dynamic_cast
1. static_cast
static_cast
官方文档:static_cast
static_cast
是静态转换,用于相关类型的转换:
int main()
{
double d = -3.14;
int a = static_cast<int>(d);
unsigned int ua = static_cast<unsigned>(d);
cout << d << endl;
cout << a << endl;
cout << ua << endl;
return 0;
}
// 输出:
// -3.14
// -3
// 4294967293
2. reinterpret_cast
reinterpret_cast
官方文档:reinterpret_cast
reinterpret_cast
用于执行低级别的转换,通常涉及指针或引用类型的重新解释,可以将任意指针类型转为另一种指针类型(较危险):
int main()
{
int a = 10;
int* p = &a;
int addr = reinterpret_cast<int> (p);
return 0;
}
输出:
3. const_cast
const_cast_cast
官方文档:const_cast
const_cast
用于添加常性或者移除常性:
int main()
{
volatile const int x1 = 101;
const int x2 = 102;
int& y1 = const_cast<int&>(x1);
int& y2 = const_cast<int&>(x2);
y1 = 201;
y2 = 202;
cout << "x1: " << x1 << endl;
cout << "y1: " << y1 << endl;
cout << "x2: " << x2 << endl;
cout << "y1: " << y2 << endl;
return 0;
}
// 输出:
// x1 : 201
// y1 : 201
// x2 : 102
// y1 : 202
4. dynamic_cast
const_cast_cast
官方文档:dynamic_cast
dynamic_cast
通常用于处理多态类型
向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)
向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)
class A
{
public:
virtual void f(){}
public:
int x_ = 0;
};
class B :public A
{
public:
int y_ = 0;
};
void func(A* pa)
{
//pa是指向子类B,可以转换,返回正常地址
//pa是指向父类A,不可以转换,返回空指针
B* pb = dynamic_cast<B*>(pa);
if (pb)
{
cout << "转换成功" << endl;
pb->x_++;
pb->y_++;
}
else
{
cout << "转换失败" << endl;
}
}
int main()
{
A aa;
func(&aa);
B bb;
func(&bb);
return 0;
}
// 输出:
// 转换失败
// 转换成功