条款24:若所有参数都需要类型转换,请为此采用non-member函数

如果你需要为某个函数的所有参数(包括this指针所的那个隐喻参数)进行类型转换,那么这个函数必须是non-member
例子:
class Rational {
public:
         Rational(intnumerator=0, int denominator=1); //不是explicit,为了支持混合运算
                                           //支持int-to-Rational隐式转换
         constRational operator* (const Rational& rhs) const; 
         intnumerator () const;
         intdenominator() const;
private:
         intn,d;
};
Rational oneEight(1,8);
Rational oneHalf(1,2);
Rational result=oneEight*oneHalf;   //正确
result=oneHalf*2;     //正确,隐式类型转换 => result=oneHalf.operator*(2); 
//即 const Rational  temp(2);result=oneHalf*temp; 构造一个临时性的Rational对象
result=2*oneHalf;     //错误 =>result=2.operator*(oneHalf);

oneHalf是一个内含operator*函数的class对象,所以编译器调用该函数。而整数2并没有相应的class,也就没有operator*可供调用。编译器会尝试寻找可被这样调用的non-menber的operator*(在命名空间中或在global作用域内),如下:
result=operator*(2,oneHalf);  //错误

	因为本例并不存在一个接受int和Rational作为参数的operator*,因此查找失败。
	上述只因为涉及non-explicit构造函数,编译器才会这么做,如果Rational构造函数是explicit的,则都不会通过编译。

result=oneHalf*2;   //错误,在explicit下,无法将2转换为Rational
resule=2*oneHalf;    //同理

而在non-explicit情况下上述表达式也只有一个通过:
result=oneHalf*2;   //在non-explicit下 正确

resule=2*oneHalf;    //错误,在non-explicit下

NOTE: 只有当参数在初始化列表(parameterlist),这个参数才是隐式类型转换合格参与者,地位相当于“被调用的成员函数所隶属的那个对象”(即this对象)的那个隐喻参数。
 
正确的做法:
class Rational{
};
//non-member函数
const Rational operator* (const Rational& lhs, constRational& rhs)
{  
return Rational(lhs.numerator()*rhs.numerator(), lhs.denominator()*rhs.denominator() ); 
}

是否需要声明为友元呢?
不需要,因为operator*可以完全由Rational的public接口完成任务。而在条款21中必须声明为友元函数,因为用到了其中的private变量。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值