Как оператор == работает вне класса в C ++ - PullRequest
0 голосов
/ 30 января 2019

Я читал CppCoreGuidelines и наткнулся на то, чего раньше не знал.По сути, это говорит о том, что я могу перегрузить, т.е. operator== вне класса, и это как-то сработает для сравнения двух объектов этого класса.Я сделал это:

#include <iostream>

class foo
{
public:
    int member;
    foo() : member(0) {}
};

bool operator==(const foo& lhs, const foo& rhs)
{
    return lhs.member == rhs.member;
}

int main()
{
    foo c1;
    foo c2;
    if (c1 == c2)
    {
        std::cout << "Even" << '\n';
    }   
}

И это действительно работает.Поэтому я начал искать объяснения в интернете.Потому что я могу представить, что если я попытаюсь сравнить объект, компилятор ищет operator== в методах этого класса, что для меня понятно.Но здесь у меня есть функция, которую, я думаю, можно определить в другом файле, она полностью независима от класса foo (только те параметры, которые ему нужны), и все же она распознается как та, которая будет использоваться для сравнения.

Итак, теперь мой вопрос: как компилятор или, я думаю, более конкретно, компоновщик находит эту функцию и использует ее для сравнения этих двух объектов?

1 Ответ

0 голосов
/ 30 января 2019

Допустим, у вас есть функция bool is_equals(const foo &lhs, const foo &rhs);.Как компилятор превращает is_equals(c1, c2) в вызов is_equals?

Ответ точно такой же , что и для operator==.Если для типа (ов) операндов нет члена operator==, компилятор пытается найти не являющийся членом operator==, используя типы операндов.Если такая вещь существует, то она вызывается, если она не существует, то она не вызывается.

Как поведет себя компилятор, если ваша перегрузка operator==, не являющаяся членом, находится в другомфайл, без заголовка, объявляющего его в файле, который вы сейчас компилируете?Ответ тот же, что и раньше: что произойдет, если вы вызовете is_equals, не заявив, что такая функция существует?

Вы получите ошибку компиляции.Не имеет значения, определена ли эта функция в другом модуле перевода;если при попытке вызвать функцию не отображается объявление, вы получаете ошибку компиляции.

Что произойдет, если два отдельных файла попытаются определить operator== с разными реализациями?Снова: то же самое, что происходит, если вы попробовали это с is_equal.Вы нарушили правило единого определения C ++ и, таким образом, вызвали неопределенное поведение.Мы надеемся, что вы получите ошибку компоновщика, но это не гарантировано.

Короче говоря, operator== не является специальной магической функцией в C ++.Это необычное имя для функции, но оно не является чем-то особенным для компилятора или компоновщика. special заключается в том, что c1 == c2 преобразуется в вызов operator==(c1, c2) (кстати, это 100% допустимый код C ++, который вы можете написать, хотя он будет вызывать только не-член operator==),Но это нечто особенное в использовании оператора, а не в синтаксисе функции C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...