@cxm-2016
2016-09-06T13:04:15.000000Z
字数 1636
阅读 2300
c++
no
作者:陈小默
C++为内置的基本数据类型提供了自动的转换方式,即使这种转换并不安全。比如,我们可以使用下列语句而不报错。
long count = 8;
double time = 11;
int side = 3.33;
上述语句是可行的,因为在C++看来,这些数值都是相同的数据类型——数字。C++不会自动转换不兼容的类型,比如将一个int类型的值赋值给一个指针变量,尽管指针的内部实现也是int。
C++中提供了自动类型转换的过程,比如下面这个过程。
Temp t = 28.5;
如果需要让一个类能够接受自动类型转换,需要给类提供一个仅含有一个参数的构造方法,当然我们也可以使用默认参数列表保证可以只接受一个参数。
Temp(double degree);
或者
Temp(double degree,double degree2=0);
当我们第一次接触这种特性的时候也许会觉得这是一种非常不错的特性,但是当我们了解其内部创建流程时也许就不会这么想了。程序会先使用构造函数Temp(double)创建一个临时Temp对象,随后采取复制的方式将内部数据复制到我们声明的对象当中去,最后销毁临时对象。
Temp t = 28.5;
可以用如下代码表示上述过程
Temp t;
{
Temp $temp = Temp(28.5);
t = $temp;
}
当了解自动类型转换的低效之后,我们决定关闭隐式转换的过程。这里,我们可以使用C++提供的explicit关键字。当我们在构造方法前加上该关键字后,我们就不能够使用隐式转换了。但是,这里需要注意的是,我们只能关闭隐式类型转换,对于显式的强制类型转换仍然不可避免。
explicit Temp(double degree);
关闭隐式转换
Temp t = 12.1;//invailidate
Temp t2 = Temp(12.1);
Temp t3 = (Temp)12.1;
由于C++对于基本数据类型会提供自动转换,所以下面的语句也是正确的
Temp t = 10;
但是我们需要注意的是,然如我们提供了两种构造方法
Temp(double d);
Temp(long l);
那么我们再次使用上述语句时就会发出编译错误。因为编译器发现int类型的数值可以匹配上述两种构造方法。于是编译器拒绝编译。
通过上面的叙述我们知道编译器能够将一个参数直接转换为对象,但是我们能不能将一个对象转换为一个基本数据类型呢?就像下面这样
Temp t = 22.0;
double d = t;
C++为了这种功能定义了专门的转换函数,其固定格式为
operator typeName();
需要注意的是:
例如将Temp转换为double的转换函数为
operator double();
加入我们在Temp类中只提供了一个类型转换方法
operator double();
那么我们在使用cout的时候可以直接使用对象了。
cout<<t<<endl;
但是如果我们声明了两种转义类型
operator double();
operator int();
那么我们再次使用cout输出的时候编译器就不知道具体要转换为哪一种类型了。
原则上说,我们最好使用显式的类型转换而不是自动的隐式转换。
1,使用explicit关键字
explicit operator int() ;
2,自定义成员方法Getter
int getNumber();
相比之下第二种方式更符合优良的编程习惯