2015-12-10 3 views
2

Я определил класс фракции следующим образом, перегружая операторы «=» & «+».Ошибка перегрузки оператора в C++

Я сделал эту программу максимально простой, чтобы показать проблему.

#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" имеет "Нет жизнеспособной перегружен '='" ошибки?

ответ

0

Вы определили назначение operator= принять Lvalue ссылку в качестве аргумента, но пытался передать ему временное. Temporaries привязаны только к const ссылки или ссылки на rvalue.

Вы должны прочитать, как перегружать операторы удобным способом, например. такая же проблема возникает при ссылках nonconst lvalue, принятых вашим operator+.

Это означает, что Fraction& operator=(Fraction const&) и Fraction operator+(Fraction const&, Fraction const&).

+1

Бесстыдный плагин: [Я написал блог пост-серии о перегрузке оператора] (http://arne-mertz.de/2015/01/operator-overloading-common-practice/), включая [класс для рациональных чисел, построенных с помощью boost.operators] (http: // arne -mertz.de/2015/02/operator-overloading-introduction-to-boost-operators-part-2/) –

1

Это потому, что ваш operator= не может привязываться к временным.

Вы должны определить это так:

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

так, он будет связываться с постоянными и временных объектов и литералов.

2

Ваш оператор назначения объявлен как ссылка на неконстантный Fraction. Оператор добавления возвращается по значению, поэтому вы пытаетесь назначить временное значение frac_c. Временные пользователи не могут связываться с неконстантными ссылками.

Исправление сделать ваше задание оператора взять по константной-ссылки:

Fraction & operator = (const Fraction &); 
+0

Вы также можете добавить 'Fraction & operator = (Фракция &&);' – Jerome

+0

@Jerome вы могли бы, но в этом случае это не имеет смысла, поскольку переход от фракции будет просто копией. – TartanLlama

+0

Я просто думаю, что это хорошая практика – Jerome

Смежные вопросы