2013-12-15 4 views
0

Я пытаюсь понять, оператор перегрузку в C++, и я побежал в этот кусок кода:Член против оператора, не являющихся членов перегрузки

class Imaginary { 
    double re,im ; 
    public: 
    Imaginary (double r, double i=0) : re(r), im(i) {} 

    Imaginary operator - (void) const;    // member 
    Imaginary operator + (const Imaginary& x) const; // member 

    friend Imaginary operator + (double a, const Imaginary& b); // non-member ? 
}; 

, который должен показать использование non-member перегрузки. Но я не понимаю, как он не является членом, когда он объявлен внутри класса? Или это зависит от количества параметров, так как + является двоичной операцией, поэтому с двумя параметрами он считается нечленом и с 1 членом?

ответ

1

Объявление friend вставляется в пространство имен, окружающее определение класса, где оно появляется. То есть декларация (пространство имен добавляются к более позднему осветления):

namespace foo { 
    class Imaginary { 
     // ... 
     friend Imaginary operator+ (double a, Imaginary const& b); 
    }; 
} 

На самом деле делает две вещи: он объявляет функцию и заявляет, что эта функция имеет право доступа ко всем членам класса Imaginary. Функция объявлена ​​вне

foo::Imaginary foo::operator+ (double a, foo::Imaginary const& b); 
+0

О теперь все ясно, я просто не понимаю, как 'friend' на самом деле работает .. Спасибо! –

1

Эта строка объявляет op+ не для членов. Это означает, что, несмотря на то, что он не является членом, он может видеть частных членов Imaginary.

friend Imaginary operator + (double a, const Imaginary& b); 

Реализация оператора будет вне класса.

0

Существует большая разница между этими двумя операторами

Imaginary operator + (const Imaginary& x) const; // member 

friend Imaginary operator + (double a, const Imaginary& b); // non-member ? 

В первом операторе члена класса левый операнд всегда типа воображаемого. Второй операнд может быть типа двойной, потому что есть конструктор преобразования

Imaginary (double r, double i=0) : re(r), im(i) {} 

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

Оператор friend позволяет указать двойной номер в качестве первого операнда операции. Опять же, если в качестве первого операнда будет указан двойной номер, будет вызываться конструктор преобразования, и на самом деле вы получите выражение

Imaginary + Imaginary.

Таким образом, оператор друг добавляет оператор-член класса позволяет следующие выражения

Imaginary + Imaginary // class member operator will be called 
Imaginary + double// class member operator will be called 
double + Imaginary // the friend operator will be called 
+0

Спасибо за ваш ответ, хотя это была не совсем моя проблема. Я просто не понял, почему некоторые методы, отличные от членов, объявляются вне класса, и другие (в этом случае метод friend) внутри. Таким образом, проблема была ключевым словом для друга, а не перегрузкой. Но еще раз спасибо за такой тщательный ответ! –

+0

На самом деле в этом конкретном случае достаточно объявить один оператор друга с двумя операндами типа const Imaginary &. –

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