重载操作符注意事项

1. 只有当参数位于参数列内, 这个参数才是隐式类型转换的合格参与者。


类中二元操作符重载的时候, 左边操作数会以this指针传入, 右边操作数会以参数列的参数传入。
所以, 如果你需要为某个函数的所有参数(包括 this 指针所指的那个隐喻参数)进行类型转换, 
那么这个函数必须是个non-member函数。


案例: 实现 Rational 的混合运算
 

#include <iostream>
using namespace std;


class Rational
{

public:

    // 构造函数刻意不为 explicit , 允许 int-to-Rational 隐式转换 
    Rational(int numerator = 0, int demominator = 1)
    {
         this->m_numerator = numerator;
         this->m_demominator = demominator;
    }
    
    // const 类型返回, 可以保证不会有把表达式进行赋值的异常操作(a*b=c)
    // 直接返回值, 可以保证多个操作对象的需要((a*b) == (c*d))
    const Rational operator*(const Rational& rhs)
    {
        return Rational(this->m_numerator * rhs.m_numerator,
                        this->m_demominator * rhs.m_demominator);
    }
    
    // const 对象只能访问 const成员函数
    int numerator() const
    {
        return m_numerator;
        
    }
    
    int demominator() const
    {
        return m_demominator;
    }

private:
    int m_numerator;
    int m_demominator;

};






int main()
{
    Rational one(1,2);
    Rational result(3,4);
    
    result = one * 3;   // 可以正常,根据运算符转换为 one.operator*(3)  ,  3为参数列, 3可以通过隐式构造函数转换
    result = 3 * one;   // 编译报错, 根据运算符转换为 2.operator*(one)  , one为参数列, 无法识别
    
    return 0;
}

解决方法: 采用 non-member函数, 将左右作为均以参数列的形式传入, 那么就可以进行隐式转换

#include <iostream>
using namespace std;


class Rational
{

public:

    // 构造函数刻意不为 explicit , 允许 int-to-Rational 隐式转换 
    Rational(int numerator = 0, int demominator = 1)
    {
         this->m_numerator = numerator;
         this->m_demominator = demominator;
    }
    
    // const 对象只能访问 const成员函数
    int numerator() const
    {
        return m_numerator;
        
    }
    
    int demominator() const
    {
        return m_demominator;
    }

private:
    int m_numerator;
    int m_demominator;

};


const Rational operator*(const Rational& lhs, const Rational& rhs)
{

    return Rational(lhs.numerator() * rhs.numerator(),
                    lhs.demominator() * rhs.demominator());
}





int main()
{
    Rational one(1,2);
    Rational result(3,4);
    
    result = one * 3;   // 可以正常,根据运算符转换为 operator*(one , 3)  ,  3为参数列, 3可以通过隐式构造函数转换
    result = 3 * one;   // 可以正常, 根据运算符转换为 operator*(3, one)  ,  3为参数列, 3可以通过隐式构造函数转换
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u011857683/article/details/81588567