forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   return и конструктор копирования (http://forum.boolean.name/showthread.php?t=16627)

impersonalis 11.04.2012 22:09

return и конструктор копирования
 
Я всегда считал, что когда функция возвращает во вне автоматическую переменную по значению (не ссылкой!) при помощи оператора return, то вызывается некий механизм копирования. Соответственно возврат в вызывающий код экземпляра класса должен провоцировать вызов его конструктора копирования.
Однако если запустить этот код:
Код:

#include <conio.h>
#include <iostream>

using namespace std;

class foo{
    private:
        int bar;
    public:
        foo();
        foo(const foo &baz);
        foo &operator=(const foo &baz);
        ~foo();
        friend foo help_function(const foo &baz);
};

foo::foo():bar(0){
    cout<<"def ctor\n";
}

foo::foo(const foo &baz){
    this->bar=baz.bar;
    cout<<"copy ctor\n";
}

foo& foo::operator=(const foo &baz){
    cout<<"operator =\n";
    this->bar=baz.bar;
    return *this;
}

foo::~foo(){
    cout<<"destroy\n";
}

foo help_function(const foo &baz){
    cout<<"call hfunc:\n";
    foo temp,real_temp;
    temp.bar=baz.bar*2;
    cout<<"return\n";
    return temp;
}

int main()
{
    foo a;
    foo b=a;
    a=b;
    cout<<"==\n";
    foo c=help_function(a);
    b=help_function(a);
    getch ();
    return 0;
}

можно :4to:
Рассмотрим детальней:
foo a; вызов конструктора по умолчанию
foo b=a; вызов конструктора копирования
a=b; вызов оператора "="
тут всё логично, но далее:

foo c=help_function(a); вызов конструктора по умолчанию дважды (внутри функции поддержки), один (!) вызов деструктора и всё - далее реакция уже на следующие инструкции
b=help_function(a); вызов конструктора дважды, один деструктор, вызов оператора = и ещё одного деструктора
Это шо жа - получается, конструкция:
Код:

foo c=help_function(a);
вовсе не уничтожает автоматическую переменную foo temp, а, пользуясь тем, что всё равно требуется создание экземпляра foo c, начинает использовать temp вместо c (c становится псевдонимом temp)?
Причём в случае:
Код:

b=help_function(a);
temp всё же удаляется за ненадобностью, но уже после выполнения операции присваивания.
А печалит здесь только одно - к.к. не вызывается. Быть может зависит от настроек компилятора (gcc)?
Пользователи студии отпишитесь, пожалуйста!

HolyDel 11.04.2012 22:35

Ответ: return и конструктор копирования
 
debug:
Цитата:

def ctor
copy ctor
operator =
==
call hfunc:
def ctor
def ctor
return
copy ctor
destroy
destroy
call hfunc:
def ctor
def ctor
return
copy ctor
destroy
destroy
operator =
destroy
msvs 11

вроде все правильно.

impersonalis 11.04.2012 22:42

Ответ: return и конструктор копирования
 
Вот у холи так, как я ожидал - а вот что у меня:
Цитата:

def ctor
copy ctor
operator =
==
call hfunc:
def ctor
def ctor
return
destroy
call hfunc:
def ctor
def ctor
return
destroy
operator =
destroy
О УЖАС!!! Это всё GCC

HolyDel 11.04.2012 22:46

Ответ: return и конструктор копирования
 
нет. это RVO
в релизе у меня тоже так

impersonalis 11.04.2012 22:49

Ответ: return и конструктор копирования
 
а у меня и в debug


Часовой пояс GMT +4, время: 01:05.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot