条款19: 分清成员函数,非成员函数和友元函数

条款19: 分清成员函数,非成员函数和友元函数
很前几章一样,先提供一个类的代码
//伪代码
class rational {
public:
rational(int numerator = 0, int denominator = 1);
int numerator() const;
int denominator() const;

const rational operator*(const rational& rhs) const;
private:
...
};

class rational //有理数
{
public:
rational(int numerator = 0, int denominator = 1);
rational& operator=(const rational& rhs);
const rational operator*(const rational& rhs);

void print();

int getX()const;
int getY()const;
private:
int x;
int y;
};
int rational::getX()const
{
return x;
}

int rational::getY()const
{
return y;
}

const rational operator*(const rational &r1, const rational &r2)
{
return rational( r1.getX()*r2.getX(), r1.getY()*r2.getY() );
}

void rational::print()
{
cout<<"x= "<<x
<<"y= "<<y<<endl;
}

rational::rational(int numerator , int denominator ):x(numerator), y(denominator)
{
}

rational& rational::operator =(const rational &rhs)
{
if(this==&rhs)
return *this;

x=rhs.x;
y=rhs.y;
return *this;
}

const rational rational::operator*(const rational& rhs)
{
rational r;
r.x=x*rhs.x;
r.y=y*rhs.y;
return r;
}


int main()
{
rational r1(5,10);
rational r2(50,100);
rational r3;
r3=2*r2;
r3.print();

system("pause");
return 0;
}

进行运算符的操作
rational oneeighth(1, 8);
rational onehalf(1, 2);

rational result = onehalf * oneeighth; // 运行良好
result = result * oneeighth; // 运行良好

result = onehalf.operator*(2); // 运行良好----->> result = onehalf * 2;
result = 2.operator*(onehalf); // 出错! ----->> result = 2 * onehalf;

这里有两个知识点,在result = 2.operator*(onehalf);result = 2 * onehalf;即这种中因为2没有这样的函数所以导致调用

出错(或者说对函数列表中非*this指针对对应的对象进行转换)。在此期间,编译器还会尝试调用result = operator*(2,

onehalf); 这样的一个非成员函数(在导入的命名空间内寻找)

result = onehalf.operator*(2); 为什么会通过?
这实际上被隐式转换了
const rational temp(2);
result = onehalf * temp; // 同onehalf.operator*(temp);

为什么有这种转换呢?涉及到explicit关键字,如果这样申明那么就禁止转换而报错了
explicit rational(int numerator = 0, // 此构造函数为
int denominator = 1); // explicit

explicit adj.外在的, 清楚的, 直率的, (租金等)直接付款的

那怎么解决呢?既然onehalf.operator*(2);这样能隐式转换,那么也希望2.operator*(onehalf)也能进行转换。但是因为函数

只对非*this对象进行转换所以如果单单依靠对象来带动函数的话是不太可能了。
effective解决的方法为设个和类名一样的空间,但是不提倡友元函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值