Этот фрагмент кода:
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();
}
Интересно, что привязка временной ссылки к константной ссылке совершенно допустима в 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();
}
int& i = * new int;