Этот фрагмент кода:
int& func1()
{
int i;
i = 1;
return i;
}
не будет работать, потому что вы возвращаете псевдоним (ссылку) для объекта с временем жизни, ограниченным областью вызова функции.Это означает, что как только func1()
возвращает, int i
умирает, делая ссылку, возвращаемую функцией, бесполезной, поскольку теперь она ссылается на объект, который не существует.
int main()
{
int& p = func1();
/* p is garbage */
}
Вторая версия работает, потому чтопеременная размещается в свободном хранилище, которое не привязано к времени жизни вызова функции.Тем не менее, вы несете ответственность за delete
выделение int
.
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int* p = func2();
/* pointee still exists */
delete p; // get rid of it
}
Как правило, вы должны заключить указатель в некоторый класс RAII и / или в заводскую функцию, чтобы вы не делалине нужно delete
делать это самостоятельно.
В любом случае вы можете просто вернуть само значение (хотя я понимаю, что приведенный вами пример, вероятно, был надуманным):
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
Примечаниечто вполне нормально возвращать большие объекты таким же образом func3()
возвращает примитивные значения, потому что почти каждый компилятор в настоящее время реализует некоторую форму оптимизации возвращаемых значений :
class big_object
{
public:
big_object(/* constructor arguments */);
~big_object();
big_object(const big_object& rhs);
big_object& operator=(const big_object& rhs);
/* public methods */
private:
/* data members */
};
big_object func4()
{
return big_object(/* constructor arguments */);
}
int main()
{
// no copy is actually made, if your compiler supports RVO
big_object o = func4();
}
Интересно, что привязка aвременно к const ссылка совершенно законна C ++ .
int main()
{
// This works! The returned temporary will last as long as the reference exists
const big_object& o = func4();
// This does *not* work! It's not legal C++ because reference is not const.
// big_object& o = func4();
}