c++类型转换
- 在学习c语言时,我们都知道可以将double类型赋值给int类型,这叫隐式类型转换,而将一个int*的地址强制转换为int类型叫做显示类型转换,那么c++中又是怎么规范的呢?一起来看看
1.c语言中的类型转换
隐式类型转换:类型相近的类型,类型相关的类型进行转换
显示类型转换:相反的,是一种不相关类型的转换
void Test ()
{
int i = 1;
// 隐式类型转换
double d = i;
printf("%d, %.2f\n" , i, d);
int* p = &i;
// 显示的强制类型转换
int address = (int) p;
printf("%x, %d\n" , p, address);
}
缺陷: 转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换,有时候会出现很bug的问题
下面的代码运行结果是死循环,因为i隐式转换为size_t类型,他永远不会小于0
int main()
{
int i = 5;
size_t pos = 0;
while (i >= pos)
{
cout << i-- << endl;
}
return 0;
}
2.c++中的强制类型转换
标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符:
- static_cast
- reinterpret_cast(瑞音特婆特_cast)
- const_cast
- dynamic_cast
2.1static_cast
static_cast适用于相关类型的转换
int main()
{
int i = 1;
double d = static_cast<double>(i);
cout << d << endl;
return 0;
}
2.2reinterpret_cast
reinterpret_cast适用于不相关类型的转换
int main()
{
int i = 1;
int* p = &i;
int address = reinterpret_cast<int>(p);
cout << address << endl;
return 0;
}
2.3const_cast
const_cast可以去掉const属性,实际上reinterpret_cast也可以完成下面代码的行为,但是因为去掉const属性是一种非常危险的事情,所以这里单独提出这种类型实际上是在高度强调去掉const是一种危险的行为,希望谨慎使用。
有经验或者自己敲过下面代码的同学实际上知道,下面还是输出2,说明第三句代码并没有改掉a,然而事实是这样的吗?
int main()
{
const int a = 2;
int* p = const_cast< int*>(&a);
*p = 3;
cout << a << endl;
return 0;
}
观察内存我们发现a实际上已经被改掉了,但是为什么打印出来还是2?
转到反汇编:我们发现,编译器已经知道了a是const类型,所以直接从寄存器中取走了2,但是实际上内存中a已经被改成了3
我们给代码加上volatile关键字,告诉编译器不要优化
volatile const int a = 2;
此时运行结果为3,再次转到反汇编:此时a从内存中取出并且打印
2.4dynamic_cast
dynamic_cast用于将一个父类对象的指针转换为子类对象的指针或引用(动态转换)
- 向上转型:子类对象指针->父类指针/引用(不需要转换,赋值兼容规则)
- 向下转型:父类对象指针->子类指针/引用(用dynamic_cast转型是安全的)
注意: 1. dynamic_cast只能用于含有虚函数的类 2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
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);//pa转换成B*会失败返回000000
fun(&b);
system("pause");
return 0;
}
3.c++为什么需要四种类型的转换
C风格的转换格式很简单,但是有不少缺点的:
- 隐式类型转化有些情况下可能会出问题
- 显式类型转换将所有情况混合在一起,代码不够清晰
总结
- 了解c语言中的类型转换,掌握c++中的4中类型转换,并且明确为什么需要4中类型转换
- 掌握4种类型转换分别应用与什么情况下,并且知道dynamic_cast是一种RTTI(运行时类型识别)