Почему компилятор позволяет функции возвращать значение, которое хранится как ссылка - PullRequest
1 голос
/ 12 апреля 2010

Кто-нибудь может объяснить, почему этот код не генерирует ошибку компилятора?

class Foo
{
   public:
      int _x;
};

Foo getFoo()
{
   Foo myfoo;
   myfoo._x = 10;
   return myfoo;
}


int _tmain()
{
   // shouldn't this line of code be a compiler error?
   Foo& badfoo = getFoo();

   return 0;
}

Ответы [ 5 ]

4 голосов
/ 12 апреля 2010

Вы, вероятно, используете VC ++, который допускает это как расширение.

main.cpp:18: warning C4239: nonstandard extension used : 
'initializing' : conversion from 'Foo' to 'Foo &'
4 голосов
/ 12 апреля 2010

Это должно быть ошибкой компиляции, хотя не было бы, если бы вместо этого

const Foo& badfoo = getFoo();

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

Код, который вы разместили, дает мне ожидаемую ошибку компиляции

ошибка: неверная инициализация неконстантная ссылка типа "Foo &" из временного типа "Foo"

на G ++ 4.3.2. Какой компилятор вы используете?

0 голосов
/ 12 апреля 2010

Вы можете привязать ссылки к временным файлам, и у них есть время жизни самой ссылки.

Если, с другой стороны, getFoo вернет Foo &, у вас возникнут некоторые проблемы, поскольку время жизни объекта закончится, когда закончится функция getFoo. Поскольку вы не возвращаете ссылку на внутренние данные, а скорее возвращаете копию этих данных, все в порядке.

0 голосов
/ 12 апреля 2010

Метод getFoo также может быть таким:

 Foo getFoo() 

{
   Foo* myfoo = new Foo();
   myfoo->_x = 10;
   return *myfoo;
}

И это нормально ... Компилятор не может знать всего:)

0 голосов
/ 12 апреля 2010

Нет. getFoo() возвращает значение, это означает, что его временная копия будет выделена, и ссылка будет ссылаться на эту копию.

...