Возвращает постоянную ссылку на локальную переменную из функции

StackOverflow https://stackoverflow.com/questions/1465851

Вопрос

У меня есть несколько вопросов по возврату ссылки на локальную переменную из функции:

class A {
public:
    A(int xx)
    : x(xx)
    {
        printf("A::A()\n");
    }
};

const A& getA1()
{
    A a(5);
    return a;
}

A& getA2()
{
    A a(5);
    return a;
}

A getA3()
{
    A a(5);
    return a;
}

int main()
{
    const A& newA1 = getA1(); //1
    A& newA2 = getA2(); //2
    A& newA3 = getA3(); //3
}

Мои вопросы таковы =>

  1. Является ли реализация getA1() правильно?Я считаю, что это неверно, поскольку оно возвращает адрес локальной переменной или временной.

  2. Какое из утверждений в main (1,2,3) приведет к неопределенному поведению?

  3. В const A& newA1 = getA1(); гарантирует ли стандарт, что временная привязка к ссылке const не будет уничтожена до тех пор, пока ссылка не выйдет за пределы области видимости?

Это было полезно?

Решение

1.Является getA1() правильная реализация ?Я чувствую, что это неверно, поскольку это возвращающий адрес локальной переменной или временной.

Единственная версия getAx() это правильно, что в вашей программе есть getA3().Оба остальных имеют неопределенное поведение независимо от того, как вы будете использовать их позже.

2.Какое из утверждений в main ( 1,2,3) приведет к неопределенному поведению ?

В каком-то смысле ни один из них.Для 1 и 2 неопределенное поведение является результатом тел функций.Для последней строки, newA3 должна быть ошибка компиляции, так как вы не можете привязать временную ссылку к неконстантной.

3.В const A& newA1 = getA1(); гарантирует ли стандарт, что временная привязка к const ссылка не будет уничтожена до тех пор, пока ссылка не выйдет за пределы области видимости?

Нет.Ниже приведен пример этого:

A const & newConstA3 = getA3 ();

Здесь, getA3() возвращает временное значение, и время жизни этого временного значения теперь привязано к объекту newConstA3.Другими словами, временное будет существовать до тех пор, пока newConstA3 выходит за рамки.

Другие советы

Q1:Да, это проблема, смотрите Ответ на вопрос 2.

Q2:1 и 2 не определены, поскольку они ссылаются на локальные переменные в стеке getA1 и getA2.Эти переменные выходят за пределы области видимости и больше недоступны, и, что еще хуже, могут быть перезаписаны, поскольку стек постоянно меняется.getA3 работает, поскольку создается копия возвращаемого значения и возвращается вызывающему объекту.

Q3:Такой гарантии увидеть ответ на вопрос 2 не существует.

Я думаю, что главная проблема заключается в том, что вы вообще не возвращаете временные файлы, вы должны

return A(5);

вместо того , чтобы

A a(5);
return a;

В противном случае вы возвращаете адрес локальной переменной, а не временной.И временная ссылка на const работает только для временных.

Я думаю, это объяснено здесь:временная ссылка на const

Если вы скомпилируете это на VC6, вы получите это предупреждение

****** Предупреждение компилятора (уровень 1) C4172 возвращаемый адрес локальной переменной или временного Функция возвращает адрес локальной переменной или временного объекта.Локальные переменные и временные объекты уничтожаются при возврате функции, поэтому возвращаемый адрес недействителен.******

Во время тестирования этой проблемы я обнаружил интересную вещь (данный код работает в VC6):

 class MyClass
{
 public:
 MyClass()
 {
  objID=++cntr;
 }
MyClass& myFunc()
{
    MyClass obj;
    return obj;
}
 int objID;
 static int cntr;
};

int MyClass::cntr;

main()
{
 MyClass tseadf;
 cout<<(tseadf.myFunc()).objID<<endl;

}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top