Класс C ++, в чем разница между оператором друга и оператором извне - PullRequest
0 голосов
/ 20 января 2012

Когда мы определяем операторную функцию внутри класса a, мы также определяем ее внутри класса, тогда эта функция НЕ является частью класса.

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

рассмотрим этот код, который имеет два идентичных определения операторов, где один находится внутри класса, а другой - вне класса:

версия 1 (внутри класса)

class MyClass
{
    // version 1 inside a class
    friend MyClass&& operator +(MyClass& a, MyClass& b)
    {
        return move(MyClass(a.x + b.x, a.y + b.y));
    }
    int x,y;

public:
    MyClass() {}
    MyClass(int,int){}
};

int main()
{
    MyClass a, b, c;
    c = a + b;
    cin.ignore();
    return 0;
}

версия 2 (вне класса)

class MyClass
{
      friend MyClass&& operator +(MyClass& a, MyClass& b);
    int x,y;

public:
    MyClass() {}
    MyClass(int,int){}
};

MyClass&& operator +(MyClass& a, MyClass& b)
{
    return move(MyClass(a.x + b.x, a.y + b.y));
}

int main()
{
    MyClass a, b, c;
    c = a + b;
    cin.ignore();
    return 0;
}

Какая разница в этих двух подходах?

Ответы [ 2 ]

4 голосов
/ 20 января 2012

В вашем случае обе версии делают одно и то же (возвращают висячую ссылку, фактически вызывая неопределенное поведение), хотя одна - inline, а две - нет.

В общем, функция другатело которого определено внутри класса, также может использовать члены класса без квалификации (это могут быть статические члены, возможно, в базовых классах, поскольку в функции друга нет указателя this).

Вот соответствующий текст встандарт (раздел 11.3 [class.friend]):

Функция может быть определена в объявлении друга класса, если и только если класс является нелокальным классом (9.8), имя функцииявляется неквалифицированным, и функция имеет область видимости пространства.

Такая функция неявно inline.Функция friend, определенная в классе, находится в (лексической) области действия класса, в котором она определена.Функция friend, определенная вне класса, не является (3.4.1).

1 голос
/ 20 января 2012

В данный момент вы определяете MyClass&& operator +(MyClass& a, MyClass& b) дважды в первом фрагменте и один раз во втором.Если вы удалите второе определение, оба будут семантически эквивалентны.

Оба будут делать то же самое.В некоторых случаях одно может быть предпочтительнее другого (например, второе может быть помещено в файл cpp, а первое может быть более естественным для шаблонов).

Обратите внимание, что первое неявно помечено как встроенное, второе не.

(Вы должны передать MyClass по константной ссылке, хотя.)

...