возвращение локального значения / ссылки - PullRequest
0 голосов
/ 26 января 2012

Этот вопрос возникает из вопросов и ответов здесь

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

Во-первых, из связанного вопроса я узнал, что возвращение ссылки на local - это ЗЛО!

Теперь рассмотрим тот же пример из этого вопроса.немного измененный:

#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
class A
{
    public:
        int x;
        string s;
        A(int xx,string ss):x(xx),s(ss)
    {
        cout<<"A::A()"<<x<<","<<s<<"\n";
    }
        A(const A& that)
        {
            cout<<"cpy ctr\n";
            x=that.x;
            s=that.s;
        }
        A& operator=(const A& that)
        {
            cout<<"operator=\n";
        }
        ~A()
        {
            cout<<"~A()"<<s<<"\n";
        }
};

const A& getA1()
{
    A a(1,"A1");
    cout<<"returning from A1\n";
    return a;
}

A& getA2()
{
    A a(2,"A2");
    cout<<"returning from A2\n";
    return a;
}

A getA3()
{
    A a(3,"A3");
    cout<<"returning from A3\n";
    return a;
}

int main()
{ 
    A &newA2 = getA2();       //.....................LINE 2
    cout<<"returned from A2\n";
    cout<<"-----------------------------\n";
    A newA3 = getA3();       //......................LINE 3
    //A const  newConstA3 = getA3 ();
    cout<<"returned from A3\n";
    cout<<"-----------------------------\n";
    //cout<<"newA2="<<newA2.x<<","<<newA2.s<<"\n";
    cout<<"newA3="<<newA3.x<<","<<newA3.s<<"\n";

}

Вывод выглядит следующим образом ..

A::A()2,A2
returning from A2
~A()A2
returned from A2
-----------------------------
A::A()3,A3
returning from A3
returned from A3
-----------------------------
newA3=3,A3
~A()A3

Теперь мои сомнения ...

  1. в LINE 2 , веселье getA2() (которое возвращается с помощью ref) возвращается после уничтожения временного объекта, поэтому получение объекта newA2 опасно для использования. (Причина, по которой я имеюзакомментировал его использование.) Итак, почему же забавное getA3() уничтожает временное, даже если оно возвращается «копией» (обратите внимание, что деструктор временного механизма внутри getA3() не вызывается когда-либо .. только newA3 вызывается деструктор объектакогда он умрет в конце main())?Я понятия не имею, куда эта температура идет ??

  2. Теперь, если в LINE 2 я изменяю его с A& newA2 = getA2(); на A newA2 = getA2();, копия CTR получаетвызывается здесь (что в конечном итоге дает ошибку по умолчанию, когда референт умер), но почему копия ctr не вызывается в LINE 3 ?Как состояние временного объекта копируется в объект newA3, уведомление также не вызывается operator=()?

  3. Наконец ... вывод здесь из gcc, но делаетMSVC ++ 2008 работает по-другому ??Как и для кода A newA3 = getA3(); в LINE 3 , он ведет себя так же, как и LINE 2 , т. Е. Разрушает темп перед возвратом!какие-нибудь подсказки?

Ответы [ 2 ]

2 голосов
/ 26 января 2012
  1. Похоже, вы получаете выгоду от Оптимизация возвращаемого значения .

  2. Поскольку вы копируете, хотя и недействительную, ссылку в новуюobject.

  3. MSVC и GCC работают в целом одинаково.Избегайте неопределенного поведения (это может быть сложнее, чем может показаться), и если они не работают одинаково, тогда есть ошибка в компиляторе.

0 голосов
/ 26 января 2012
  1. Ну, конечно, возвращаемое значение не уничтожается, иначе вы никогда не сможете вернуть что-либо из функции. Я полагаю, что он переходит прямо в стек вызывающей области после копирования его из локальной области.

  2. Копировать разрешение. Когда копия является чрезмерной (как это было бы здесь), компилятору разрешается исключить ее (даже если она имеет побочные эффекты) как своего рода предписанная стандартом «оптимизация». Это задокументировано во многих, многих вопросах по SO.

  3. Непонятно, о чем ты спрашиваешь. Вы не показали два результата для сравнения.

...