此文编写参考狄泰软件学院唐佐林老师的视频课程,如有错误之处,欢迎指正。
一、类型转换纲要
1、基本类型的转换
----隐式转换(危险性)和显式转换(4种匹配)
int a=-2000;unsigned int b=1000;a+b>0;//危险之处
四种显式转换
static_cast
reinterpret_cast
dynamic_cast
const_cast
2、基本类型到类类型,类类型到基本类型和其他类类型之间的转换
----通过转换构造函数(如何杜绝隐式转换问题)实现基本类型到类类型之间的转换
----通过类型转换函数实现类类型到基本类型和其他类类型之间的转换
----工程实践中通过Type toType()公有成员函数来代替类型转换函数,因为类型转换函数和转换构造函数具有同等地位,避免两者发生冲突。
二、深度剖析
1、隐式和强制类型转换
(1)、隐式类型转换
类型转换包括隐式转换和强制转换,实际上隐式转换是非常危险的,为什么呢?首先我们先来了解一下隐式转换。
转换关系表如下所示:
系统默认的隐式转换规则是小类型转换成大类型,因为大类型空间大,能表达的数据自然也就大,小类型到大类型的转换可以避免数据的截断或者是丢失,但是同时也会带来问题,下面用实例说明隐式转换多带来的危险。
#include<iostream>
using namespace std;
int main()
{
short s='a';
int a=-2000;
unsigned int b=1000;//无符号整型
double c=a;//小类型到大类型
cout<<c<<endl;
cout<<a+b<<endl;//会进行隐式转换
if((a+b)>0)//大于0
{
cout<<"positive"<<endl;
}
else
{
cout<<"negative"<<endl;
}
cout<<"sizeof(s+'b')="<<sizeof(s+'b')<<endl;//小类型隐式转换到大类型
return 0;
}
分析:运行结果显示,对程序设计者而言,a+b的结果应该是小于0的,但是却大于0了,这是为什么呢?原因就是编译器对不同类型做了隐式转换,int->unsigned int,也就是有符号数据变成了无符号数据,再如代码中sizeof(s+‘b’)按照设想应该是2个字节才对,但是因为高效的处理方式都是4个字节来处理的,所以short->int,char->int ,所以最后就是4个字节了。所以在编写程序时,要尽量避免隐式转换,以免带来bug。
(2)、强制类型转换
在c语言中,强制类型转换在任意类型之间都可以转换,所以非常的粗暴,这也导致了许多的错误发生,且当代码量大的时候,很难定位出错的地方,因此c++对c语言中的强制类型转换做了改进。在c++中,将强制类型转换分为4种类型:
static_cast
dynamic_cast
reinterpret_cast
const_cast
下面分别对这几种类型转换做出举例说明:
(1)const_cast,用于除去变量的只读属性,强制转换的目标类型必须是指针和引用。
语法:const_cast<type-name>(expression)
原因:有时候可能需要这样的一个值,它在大多时候是常量,而有时又是可以修改的
注意:type-name和expression的类型必须一致。如:
High bar;
const High* pbar=&bar;
......
High* pb=const_cast\<High*>(pbar);//valid
const Low* p1=const_cast\<Low*>(pbar);//invalid
例程1:
#include<iostream>
using namespace std;
void const_cast_demo()
{
int a=20;
const int& b=a;
const int* c=&a;
//b=1;//因为b是只读变量
//*c=2; //指针指向的数据不可改变
int& yinyong=const_cast<int&>(b);//去除只读属性
int* zhizhen=const_cast<int*>(c);//去除只读属性
yinyong=1;
cout<<"yinyong="<<yinyong<<endl;
cout<<"a="<<a<<endl;
*zhizhen=2;
cout<<"*zhizhen="<<