Перегрузка оператора C ++ - Перегрузка оператора вывода «<<» - PullRequest
3 голосов
/ 06 декабря 2011

Я только начинаю изучать базовый синтаксис C ++, и я немного запутался в фрагменте кода, с которым столкнулся.

Для класса, созданного с именем MyString, была перегрузка оператора, определяемая как:

ostream& operator<<(ostream& os, const MyString& s)
{
    os << s.data;
    return os;
}

Затем в некоторой функции драйвера запускается оператор:

cout << s3 << endl;

где s3 имеет тип объекта MyString.Результат выводит значение s3.

Я не совсем понимаю, как работает это утверждение.После игры с ним кажется, что конструктор копирования вызывается один раз, а затем 3 объекта деконструируются.Как именно эта линия работает?Кажется, что оператор принимает ссылку на ostream и MyString, но не endl, ни?Кроме того, почему должен быть вызван только один конструктор копирования, когда используются два экземпляра «<<»?Может быть, я даже не задаю правильные вопросы, или мои вопросы даже не имеют смысла, потому что я действительно смущен тем, что происходит в этих строках.Если это так, кто-то может объяснить, пожалуйста, только общее объяснение того, что происходит? </p>

Ответы [ 5 ]

7 голосов
/ 06 декабря 2011

Это очень общий вопрос, но я попытаюсь прояснить ваше недопонимание.

Когда вы говорите ostream& operator<<(ostream& os, const MyString& s) { ... }, вы просто определяете функцию, которая принимает ostream& в качестве первогопараметр и const Mystring& в качестве второго параметра и возвращение ostream&.Функция имеет имя operator<< и может вызываться с помощью сокращенного синтаксиса x << y для вызова operator<<(x, y).

Когда вы делаете cout << s3 << endl;, это то же самое, что и operator<<(operator<<(cout, s3), endl);.

Из этого кода не вызывается ни конструктор копирования, ни деструктор для MyString.Сообщения, которые вы видите, откуда-то еще.

1 голос
/ 06 декабря 2011

Вы можете немного разбить его:

cout // this is the ostream your inserting to (stdout)
  << s3 // this calls your defined operator that writes s.data
  << endl; // this calls the operator<< for std::endl

ostream& operator<<(ostream& os, const MyString& s)
{
    // here os is the ostream (stdout) you're using via cout
    // s is s3 that you passed in
    os << s.data; // this calls operator<< for data
    return os; // this returns the reference so the subsequent call to << endl can append to the stream
}
0 голосов
/ 06 декабря 2011

Правила языка гласят, что если функция, не являющаяся членом (оператор << не является функцией-членом класса MyString), определена в том же пространстве имен, что и MyString, то эта функция, не являющаяся членом, может быть выбрана компилятором для решения этой проблемы.позвоните (как объяснил один из респондентов). Я не использую здесь стандартную терминологию, если у кого-то есть более точное описание этого принципа, пожалуйста, сообщите нам. </p>

0 голосов
/ 06 декабря 2011

Я предполагаю, что ваш компилятор может сгенерировать конструктор копирования для cout .Поток - довольно сложный объект, но выбор c ++ состоит в том, чтобы предоставить такой синтаксический сахар (как встроенные конструкторы) для абстрагирования некоторых деталей.В других ответах уже указывалось на тот важный момент, что при использовании ссылок для передачи параметров копирование не производится.

0 голосов
/ 06 декабря 2011

Конструктор копирования MyString не требуется для вызова этого оператора, поскольку MyString передается как ссылка на пользовательский оператор << для MyString. </p>

В конце не отправлено пользовательскому оператору << для MyString. </p>

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