《Effective C++》条款21:必须返回对象时,别妄想返回其reference; 24:若所有参数皆需类型转换,请为此采用non-member函数

实现一个有理数类:

class Rational {
//friend const Rational operator* (const Rational& lhs, const Rational&rhs);
//friend bool operator== (const Rational& lhs, const Rational&rhs);
public:
    Rational(int numerator = 0, int denominator = 1) : n(numerator), d(denominator) {}

    int numerator() const {return n;}
    int denominator() const {return d;}
private:
    int n;
    int d;
};

const Rational operator* (const Rational& lhs, const Rational&rhs)
{
    return Rational(lhs.numerator()*rhs.numerator(), lhs.denominator()*rhs.denominator());
}

bool operator== (const Rational& lhs, const Rational&rhs)
{
    if(lhs.numerator() / lhs.denominator() == rhs.numerator() / rhs.denominator()) return true;
    return false;
}

int main(int argc, char *args[])
{
    Rational a(10,1), b(100,1), c(1000,1), d(10000,1);
    if (a*b == c*d)
        cout << "yes" << endl;
    else 
        cout << "no" << endl;
    
    system("pause");
    return 0;
}

有理数类的operator*函数需返回新对象Rational, 所以不要妄想返回reference, 因为局部对象会在函数结束之后销毁.

有理数类的operator*函数可以声明为member函数,也就是只接受一个参数,乘号*左边为调用对象本身。这种方式不能支持如下的调用:

Rational oneHalf(1,2);
Rational result = 2 * oneHalf;
因为如上调用实则发生了:

result = 2.operator*(oneHalf);
整数2没有对应的class, 也就没有operator*成员. 编译器报错.

而对于如下的调用可以编译通过:

result = oneHalf * 2;

因为编译器对2进行了隐式类型转化,生成了一个临时Rational对象. 所以, 如果Rational的构造函数是explicit的,那么以上调用依然无法编译通过。

所以如果需要为某个函数的所有参数(包括被this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member.

另外,member函数的反面是non-member,而不是friend. 无论何时都应该避免friend函数







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值