Работает ли оператор перегрузки << в классе?
-
27-10-2019 - |
Вопрос
Я имею в виду, я пытался перегрузить оператора << внутри класса
как это
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 -й аргумент оператору «<<».
Лучший способ перегрузить «<<» - это использование функции друга, потому что таким образом вы можете сделать свой перегруженный оператор.