Перегрузка <<оператор и рекурсия

Я попробовал следующий код:

#include <iostream>
using std::cout;
using std::ostream;

class X
{
public:
    friend ostream& operator<<(ostream &os, const X& obj) 
    {
        cout << "hehe";          // comment this and infinite loop is gone
        return (os << obj);
    }
};

int main()
{
    X x;
    cout << x;
    return 0;
}

Когда я компилирую и выполняю это, это как ожидалось; бесконечный цикл. Если я удаляю cout оператор в друге функционирует, рекурсии не происходит. Почему это так?

5
задан legends2k 1 March 2010 в 10:58
поделиться

2 ответа

Оптимизатор решает, что все ваши оставшиеся действия не имеют никакого эффекта, и оптимизирует их. Правильно это или нет - другой вопрос.

В частности:

X x;

создает пустой объект «x»

cout << x;

вызывает:

return (os << obj);

, который добавляет пустой объект; компилятор замечает, что 'os' не выросла с момента последнего вызова, и не показывает никаких обещаний, что делает это дальше (и ничего больше не происходит), поэтому он решает, что весь бизнес избыточен и может быть сокращен на этом этапе.

Если вы вызываете

    cout << "hehe";          // comment this and infinite loop is gone

, происходит некоторая дополнительная активность, поэтому оптимизатор не удаляет следующий вызов.

Думаю, если вы инициализируете x чем-нибудь непустым или выполняете любое ненулевое действие, кроме cout << "хехе"; , у вас будет запущена рекурсия все равно.

7
ответ дан 18 December 2019 в 14:44
поделиться

В обоих случаях (с написанием «хе-хе» и без него) Visual Studio 2005 выдает следующее предупреждение:

warning C4717: 'operator<<' : recursive on all control paths, function will cause runtime stack overflow

В обоих случаях он компилируется и в обоих случаях это дает переполнение стека.

Однако без «хе-хе» переполнение стека происходит немного раньше.

6
ответ дан 18 December 2019 в 14:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: