警惕C++隐式转换(More Effectiv C++_5(运算符))

来源:互联网 发布:ansys软件报价 编辑:程序博客网 时间:2024/04/29 17:05

C++的类型转换,对于显示类型,C++定义了四种新的类型类型转换,即static_cast、dynamic_cast、const_cast、reinterpret_cast;当然C++也继承了C语言的特性,也可以用C中转换格式,即小括号;
对于隐式转换,C++允许编译器在不同类型之间执行转换,它继承了C语言的一些特性,允许默默的将char转换成int、short转换成double等等;
你对这些转换无法改变,它们是语言提供的。但是,对于我们自己定义的类时,常常存在一些隐式转换,这些使我们能够控制的;即单变量构造和隐式类型操作符。下面我们来谈谈这两种情况


一、单自变量构造函数
所谓单自变量构造函数是指能以单一自变量成功调用的构造,如此的构造可能声明单一的参数,也可能声明拥有多个参数,并且除了第一个参数之外都有默认值。

class A{public:     A(int x,int y=10){};private:    int b;    int c;};void fun(A x){    cout<<"SUCCESS"<<endl;}int main(){    A obj(10);    fun(obj);    int obj2=10;    fun(obj2);    return 0;}

对于上面的代码,能正确编译运行,fun(obj2)为什么没有错了?
fun本应该接收的参数类型是A,现在传递的是int参数,确能通过编译?
原因是C++可以用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换,即使用一个int类型对象作为实参传给fun函数,编译器使用接收一个int的A的构造函数从obj2生成一个新的A对象,新生成的(临时的)A的对象被传递给fun函数。
注意:对于可以发生隐式转换的构造函数,其参数可能是单一参数(有无默认均可),或者是拥有多个参数,并且除了第一个参数外均有默认值(第一个实参也可以有默认值);

A(int x,int y){};//错误,不能将int转换成A类型A(int x,int y=10){};//正确,可以发生隐式转换A(int x=10,int y=10){};//正确,可以发生隐式转换A(int x=10){};//正确A(int x){};//正确

但是,我们有时不需要隐式转换,且最好不要提供隐式转换函数,除非你确定需要它们;那么对与这种单变量构造的形式,我们只要将构造函数声明为explicit,那么编译器就不能因隐式类型的转换需要去调用它们了,不过显式类型转换仍然允许;

explicit A(int x=10){};//错误,不能通过隐式转换fun(static_cast<A>(obj2));//正确,C++新式强制转换fun((A)(obj2));//正确,C旧式转换

注:explicit关键字只能用于类内部的构造函数声明上。在类的定义体外部所做的定义上不再重复它;


二、隐式类型操作符operator
operator除了重载运算符以外,还有一个作用,就是隐式类型转换;操作格式如下:

T1::operator T2()const;//T1是类型名,T2是要转换成的类型

需要注意几点:

 1. 你不能为此函数指定返回值类型,因为返回值类型已经体现在函数名称上; 2. 需要一个return语句,来返回T2类型; 3. 常与const连用 4. 最好不要有隐式转换

参考:More Effective C++中文版(侯捷译)

0 0
原创粉丝点击