Ostream << перегрузка путаницы - PullRequest
4 голосов
/ 24 августа 2011

Когда вы перегружаете оператор << для класса (представьте, что в SomeClass это определено как друг), почему вы оба берете ссылку на ostream и возвращаете этот ostream? </p>

ostream& operator<<(ostream& s, const SomeClass& c) {
    //whatever
    return s;
}

Какая выгода может быть при возврате ostream, если он уже был напрямую изменен по ссылке?Это кажется мне излишним - хотя я уверен, что это не так:

Ответы [ 4 ]

5 голосов
/ 24 августа 2011

Позволяет «связывать» выходные данные вместе. Как в:

std::cout << someObj << someValue;

Это эквивалентно чему-то вроде:

operator<<(operator<<(std::cout, someObj), someValue);
4 голосов
/ 24 августа 2011

Это не избыточно, но полезно для цепочки вызовов. Это легче увидеть с помощью таких функций, как std :: string :: append, поэтому я начну с этого:

std::string mystring("first");
mystring.append(" second");
mystring.append(" third");

можно переписать как:

std::string mystring("first").append(" second").append(" third");

Это возможно, потому что .append () возвращает ссылку на измененную строку, поэтому мы можем продолжать добавлять .append (...) в конец. Код, связанный с тем, что вы делаете, меняется от этого:

std::cout << "first";
std::cout << " second";
std::cout << " third";

в это. Так как оператор << возвращает поток, мы также можем объединить их в цепочку! </p>

std::cout << "first" << " second" << " third";

видите сходство и полезность?

4 голосов
/ 24 августа 2011

Так что вы можете написать цепной вызов operator<< как:

stream << s1 << s2 << s3 ;

Если вы не вернете ostream&, вы не сможете написать его более одного раза.

Вы можете думать об этом как:

 operator<<(operator<<(operator<<(stream, s1), s2), s3);

или как

 ((stream << s1) << s2) << s3 ;

Сначала (stream << s1) возвращает stream&, для которого вы снова вызываете <<, и он становится stream << s2, который возвращает stream&, для которого вы снова вызываете <<, и он становится stream << s3.

1 голос
/ 24 августа 2011

Ах, это такой связанный вывод, как

cout << "this" << "is" << "ручка" << endl; </p>

все еще будет работать.

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