return SomeClass()
От: Init64  
Дата: 16.02.06 17:59
Оценка:
class TestClass
{
public:
    TestClass() { std::cout << "TestClass()" << std::endl; }
    ~TestClass() { std::cout << "~TestClass()" << std::endl; }

    TestClass& operator << (int i) { std::cout << "<< " << i << std::endl;  return *this; }
};

TestClass TestFunc()
{
    return TestClass();
}
int main()
{
    TestFunc() << 100 << 200;
}


Вопреки своим ожидания, вижу на консоли следующие строки:
TestClass()
<< 100
<< 200
~TestClass()

В моем представлении все должно отработать так:

1) return создает локальный экземпляр внутри TestFunc()
2) Далее он делает копию экземпляра, которая уже попадает в область видимости main()
3) Для локального объекта при выходе из TestFunc() вызывается деструктор ~TestFunc()
4) Для созданной копии срабатывает оператор <<

Те сначала должен отработать деструктор, и только потом <<. На консоли ожидал увидеть следующее:

TestClass()
~TestClass()
<< 100
<< 200


Как это работает на самом деле?
Re: return SomeClass()
От: srggal Украина  
Дата: 16.02.06 18:05
Оценка:
Здравствуйте, Init64, Вы писали:

Жто есть Named Return Value Optimization.

Я же здесь
Автор: srggal
Дата: 16.02.06
давал ссылку на NRVO, прочитайте.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[2]: return SomeClass()
От: Init64  
Дата: 16.02.06 18:16
Оценка:
Здравствуйте, srggal, Вы писали:

S>Здравствуйте, Init64, Вы писали:


S>Жто есть Named Return Value Optimization.


S>Я же здесь
Автор: srggal
Дата: 16.02.06
давал ссылку на NRVO, прочитайте.


Да да, сабж как раз и вызван обсуждением логов). Сейчас прочитаю ссылку. Еще одна особенность:

TestClass tc = TestFunc();


В случае наличия присваивания деструктор ~TestClass() не вызывается!
Re[2]: return SomeClass()
От: Init64  
Дата: 16.02.06 18:25
Оценка:
Здравствуйте, srggal, Вы писали:

S>Здравствуйте, Init64, Вы писали:


S>Жто есть Named Return Value Optimization.


S>Я же здесь
Автор: srggal
Дата: 16.02.06
давал ссылку на NRVO, прочитайте.


Этот код я компилировал еще в MSVC 2003. А там вроде NRVO даже близко не пахнет. Так что теоритически все должно отработать так как я описал в первом посте. Вопрос по-прежнему остается открытым.
Re[3]: return SomeClass()
От: srggal Украина  
Дата: 16.02.06 18:37
Оценка:
Здравствуйте, Init64, Вы писали:

I>Этот код я компилировал еще в MSVC 2003. А там вроде NRVO даже близко не пахнет. Так что теоритически все должно отработать так как я описал в первом посте. Вопрос по-прежнему остается открытым.


Если я все правильно понимаю, то я сам виноват в том, что Вы запутались


TestClass TestFunc()
{    
    TestClass        a; // Named RVO
    return a;
}

TestClass TestFunc()
{    
    return TestClass(); // RVO
}


Попробуйте скомпилировать вариант с NRVO, в 2003 — он не должен Вас удивить.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[4]: return SomeClass()
От: Init64  
Дата: 16.02.06 18:51
Оценка:
Здравствуйте, srggal, Вы писали:

S>Здравствуйте, Init64, Вы писали:


I>>Этот код я компилировал еще в MSVC 2003. А там вроде NRVO даже близко не пахнет. Так что теоритически все должно отработать так как я описал в первом посте. Вопрос по-прежнему остается открытым.


S>Если я все правильно понимаю, то я сам виноват в том, что Вы запутались


S>

S>TestClass TestFunc()
S>{    
S>    TestClass        a; // Named RVO
S>    return a;
S>}

S>TestClass TestFunc()
S>{    
S>    return TestClass(); // RVO
S>}

S>


S>Попробуйте скомпилировать вариант с NRVO, в 2003 — он не должен Вас удивить.


Все хорошо, но в 2003 нет ни слова про NRVO
Re[5]: return SomeClass()
От: srggal Украина  
Дата: 16.02.06 19:05
Оценка:
Здравствуйте, Init64, Вы писали:


S>>Попробуйте скомпилировать вариант с NRVO, в 2003 — он не должен Вас удивить.

Имелось в виду, что при таком варианте
TestClass TestFunc()
{    
    TestClass        a; // Named RVO
    return a;
}


Вывод будет соответсвовать вашим ожиданиям, поскольку в данном сварианте речь идет об NTVO, который 2003 не поддерживает.

I>Все хорошо, но в 2003 нет ни слова про NRVO


Я же Вам написал, что я Вас запутал, Ваш случай — это RVO, и его 2003'я поддерживает ( хотя на M$ не могу найти соответсвкюшую ссылку )
... << RSDN@Home 1.1.4 stable rev. 510>>
Re: return SomeClass()
От: _JoKe_  
Дата: 17.02.06 15:28
Оценка:
Здравствуйте, Init64, Вы писали:

I>
I>class TestClass
I>{
I>public:
I>    TestClass() { std::cout << "TestClass()" << std::endl; }
I>    ~TestClass() { std::cout << "~TestClass()" << std::endl; }

I>    TestClass& operator << (int i) { std::cout << "<< " << i << std::endl;  return *this; }
I>};

I>TestClass TestFunc()
I>{
I>    return TestClass();
I>}
I>int main()
I>{
I>    TestFunc() << 100 << 200;
I>}
I>


I>Как это работает на самом деле?


работает правильно
/*
I>    TestFunc() << 100 << 200;
это то же самое что и
*/
{
TestClass tmp; /* tmp.TestClass(); */
TestClass &tmp1 = tmp.operator<<( 100 );
TestClass &tmp2 = tmp1.operator<<( 200 );
}/*tmp.~TestClass(); */
... << RSDN@Home 1.1.4 @@subversion >>
Re[2]: return SomeClass()
От: _JoKe_  
Дата: 17.02.06 15:31
Оценка: :)
I>>TestClass TestFunc()
I>>{
I>> return TestClass();
I>>}

если ты имеешь ввиду почему здесь не создается темповый объект так ты конструктор копирования объяви должен появится
... << RSDN@Home 1.1.4 @@subversion >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.