Перегрузка перегруженных операторов - PullRequest
1 голос
/ 03 января 2012
#include <iostream>
#include <fstream>
using namespace std;

class binaryOperators 
{
    public:
        int i;

        binaryOperators (int tempI = 0)
        {
            i = tempI;
        }

        binaryOperators operator<< (const binaryOperators &right);
};

binaryOperators operator<< (const binaryOperators &left, const binaryOperators &right)
{
    cout << "\nOne";
    return left;
}

binaryOperators binaryOperators :: operator<< (const binaryOperators &right)
{
    cout << "\nTwo";
    return *this;
}

int main ()
{   
    binaryOperators obj;

    // Compiler's behavior: This statement calls the overloaded operator << declared inside the class.
    obj << 5 << 3 << 2;
    // Compiler's behavior: This statement calls the overloaded operator << declared outside the class.
    2 << obj;

    return 0;
}

Я написал комментарии внутри функции main().
В чем причина такого рода поведения компилятора?

Зависит ли это поведение компилятора?

GCC в Linux

Ответы [ 2 ]

2 голосов
/ 03 января 2012

Это поведение имеет полный смысл:

  • Когда функция-член существует и совпадает, то лучше использовать ее в предпочтении перед свободной функцией, в противном случае используйте код вне классаможет непреднамеренно нарушить инкапсуляцию класса (например, если другая функция-член будет использовать operator<<).

  • Автоматическое преобразование работает путем создания списка функций-кандидатов и затем пытаетсянайти преобразования для любых параметров, которые требуют этого.Чтобы найти функцию-член, перед построением списка кандидатов должно произойти преобразование, поэтому будет найдена только свободная функция.

2 голосов
/ 03 января 2012

Поведение, которое вы видите, обусловлено правильной константой. Оператор <<, определенный в классе, является неконстантным, поэтому он может работать только с неконстантным объектом или ссылкой, такой как obj. Версия, не являющаяся членом вне класса, имеет два постоянных операнда. </p>

Если бы вы написали версию участника как не-члена, это выглядело бы так:

binaryOperators operator<< (binaryOperators &left, const binaryOperators &right)
{
    cout << "\nTwo";
    return left;
}

При сопоставлении перегрузки компилятор выбирает наилучшее соответствие. В первом случае левый операнд не является константным, поэтому он выбирает оператор-член. Во втором случае левый операнд - это rvalue (временные двоичные операторы), на который ссылается как const, поэтому выбирается не являющийся членом оператор.

...