Вопрос

Я имею в виду, я пытался перегрузить оператора << внутри класса

как это

 class A {
      public:
           ostream &operator<<(ostream &os);// which doesnt work

      private:
           friend ostream &operator<<(ostream &os, const A& a); //Works
           int i;

 };

  Definition
          ostream &operator<<(ostream &os, const A& a) {
              os<<a.i;
              return os;
          }

Почему я не могу перегрузить оператора в класс, специфичный для класса? Или я что -то упускаю? Или я глуп, чтобы даже думать? Пожалуйста, порекомендуйте.

Это было полезно?

Решение

Функция участника:

ostream &operator<<(ostream &os);

делает Работайте, но не для ситуации, которую вы хотите. Это будет вызвано, когда вы делаете что -то вроде:

A a;
a << std::cout;

т.е. где объект является левой стороной оператора.

Другие советы

Проблема в том, что ваш operator<< взял бы ostream как второй параметр, не первый. Таким образом, вы могли бы сделать myObject << std::cout, но это будет выглядеть неинтуитивно, и вы не сможете цепорить звонки из -за operator<< Быть левой ассоциативной.

Еще одним преимуществом объявления оператора как друга в отличие от функции участника является то, что могут произойти автоматические преобразования. Это означает, что если у вас есть класс B это не происходит из A но имеет B(A const&) конструктор, вы все равно сможете сделать std::cout << my_b; и сделать это в A а затем напечатано.

К счастью, определение operator<< Как друг может быть сделан в классе, если вы предпочитаете. Ваш код может быть написан как

class A {
    int i;
    friend std::ostream& operator<<(std::ostream& o, A const& a) {
        o << a.i;
        return o;
    }
};

Почему стандарт не позволяет вам указать, какую сторону следует продолжать аргумент? Давайте притворимся, и добавим left_of а также right_of Ключевые слова для указания:

struct B;

struct A {
     A left_of operator+(B const&) {
         return *this;
     }
};

struct B {
     B right_of operator+(A const&) {
         return *this;
     }
};

Что происходит сейчас, когда мы делаем A a; B b; f(a + b);? У каждого класса есть оператор, который занимается этим делом, что означает, что мы не можем решить. В любом случае, видя, как многие операторы должны быть друзьями из -за возможностей конверсии, не допустить, чтобы такие вещи не были такой большой проблемой, и предотвращает такие неясности. (Конечно, вы также можете определить оператора участника и свободный, что вызовет очень похожую проблему.)

Кстати, как и все, определение вашего friend operator<< ничего не возвращает, что испортит цепочки.

Помните, что для не статичной функции члена класса первого аргумента является указатель. Таким образом, подпись вашей функции «Оператор <<» после того, как компиляция станет:

ostream &operator<<(A *this, ostream &os);

Это будет работать, когда вы сделаете что -то вроде:

A obj;
obj << std::cout;

Думайте о «obj» как о первом аргументе и «std :: cout» как 2 -й аргумент оператору «<<».

Лучший способ перегрузить «<<» - это использование функции друга, потому что таким образом вы можете сделать свой перегруженный оператор.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top