转换操作符定义
类可通过一个实参调用的非explicit构造函数定义一个隐式转换(其他类型—>类类型)。当提供了实参类型的对象而需要一个类类型的对象时,编译器将使用该转换。这种构造函数定义了到类类型的转换。例如
Class A{ A(int){};//非explicit构造函数}Func(A a);Int num;Func(num);//调用的时候通过int类型的也能调用,因为执行能构造函数的隐式转换。
除了其他类型通过构造函数转换为类类型以外,我们可以通过定义转换操作符(类类型——>其他类型)。
class SmallInt{public: SmallInt(int i=0):val(i){} { If(i<0||i>255) throw std::out_of_range(“Bad smallIntinitialization”); } operator int()const //转换函数,int类型为要转换的类型 { return val; }private: Std::size_t val;}
使用转换操作符有下注意点
(1)转换函数必须是成员函数,不能定义返回类型,并且参数必须为空。
(2)转换函数一般不应该改变被转换的对象,所以被定义为const成员函数。
(3)转换操作符可以不必与所需要的类型完全匹配
Func(double);SmallInt sm;//这样调用时没有问题的,SmallInt先转换为int类型,由int类型再转换为double类型。Func(sm);
(4)只能应用一个类类型转换,类类型转换之后不能再跟另一个类类型转换
class Integral{public: operator SmallInt()cosnt //定义了到Smallint类型的转换 {}}Func(intd);Integral intVal;//这个调用时错误的,虽然SmallInt定义了到int的转换,但是这产生了两次转换不对Func(intVal);
(5)使用构造函数执行隐式转换,构造函数的参数类型可以不必完全与所提供的类型匹配。
Func(SmallInt);short sobj;Func(sobj);//可以调用SmallInt(int)构造函数将short类型转换为SmallInt。
转换操作符与类构造函数隐式转换存在的二义性
(1)由于类中定义了多个转换符而存在二义性
class SmallInt{public:operator int()const; //到int类型的转换operator double()const; //到double类型的转换}Func(long double);SmallInt si;//这个定义就存在二义性,因为不知道调用哪个转换函数,都可以转换为相应的类型。Func(si);
(2)由于类中定义了多个构造函数隐式转换而造成二义性
class SmallInt{public:SmallInt(int);//int到SmallInt的隐式转换SmallInt(double);// double到SmallInt的隐式转换}Func(SmallInt);long l;//用long类型去调用就存在二义性,不知道采用哪个隐式转换Func(l);
(3)由转换操作符和默认构造函数隐式转换造成的二义性
class SmallInt{public: //接受Integral类型的构造函数,可以执行隐式转换 SmallInt(Integral);}class Integral{public:operator SmallInt();// 到SmallInt转换}Func(SmallInt);Integral val;//这时就存在二义性,不知道调用哪个转换Func(val);
注:上面所以的二义性,可以通过显示指定某种转换来避免,即指定显示转换或者显示构造函数
避免二义性
(1)最好不要给一个类定义多个类型转换符;
(2)将构造函数声明为exliplict,调用的时候使用显示转换;
(3)避免两个类使用互相转换;
重载、转换和操作符
(1)确定候选函数;
(2)选择可行函数;
(3)选择最佳匹配函数