C++中的运算符过载故障

Operator Overloading Failure in C++

本文关键字:故障 运算符 C++      更新时间:2023-10-16

我如下定义了Fraction类,重载了"="&"+"运算符。

我把这个程序做得尽可能简单,以显示问题。

#include <iostream>
class Fraction {
private:
    int nominator;
    int denominator;
public:    
    Fraction ();
    Fraction (int, int);
    Fraction & operator = (Fraction &);
    friend Fraction operator + (Fraction &, Fraction &);
    // static function:
    // find the Greatest Common Divisor of two numbers
    int static GCD(int x, int y);
};
int Fraction::GCD(int x, int y) {
    if (y == 0) {
        return x;
    } else {
        return GCD (y, x % y);
    }
}
Fraction::Fraction () {
    nominator = NULL;
    denominator = NULL;
}
Fraction::Fraction (int num_1, int num_2) {
    int divisor = Fraction::GCD (num_1, num_2);
    nominator = num_1 / divisor;
    denominator = num_2 / divisor;
}
Fraction & Fraction::operator = (Fraction &A) {
    nominator = A.nominator;
    denominator = A.denominator;
    return *this;
}
Fraction operator + (Fraction &A, Fraction &B) {
    int nominator = A.nominator * B.denominator + B.nominator * A.denominator;
    int denominator = A.denominator * B.denominator;
    int divisor = Fraction::GCD (nominator, denominator);
    return Fraction (nominator / divisor, denominator / divisor);
}

在Main()函数中,我有三个测试用例

int main(int argc, const char * argv[]) {
    Fraction frac_a = Fraction(1, 3);
    Fraction frac_b = Fraction(1, 4);
    // test 1: no compile error 
    frac_a + frac_b;
    frac_a = frac_b;
    // test 2: no compile error
    Fraction frac_c = frac_a + frac_b;
    // test 3: Error: No viable overloaded '='
    Fraction frac_d;   
    frac_d = frac_a + frac_b;
    return 0;
}

问题是,为什么"测试3"会出现"没有可行的重载'='"错误?

您的赋值运算符被声明为引用非常量Fraction。您的加法运算符按值返回,因此您正试图为frac_c分配一个临时运算符。临时变量不能绑定到非常量引用。

修复方法是使您的赋值运算符采用常量引用:

Fraction & operator = (const Fraction &);

这是因为您的operator=无法绑定到临时库。

你应该这样定义它:

Fraction & Fraction::operator = (const Fraction &A)

因此,它将绑定到临时对象、常量对象和文字。

您将赋值operator=定义为将左值引用作为参数,但试图将其传递为临时的。临时值仅绑定到常量引用或右值引用。

您应该了解如何以可用的方式重载运算符,例如,operator+接受的非约束左值引用也会出现同样的问题。

也就是说,使用Fraction& operator=(Fraction const&)Fraction operator+(Fraction const&, Fraction const&)