Я знаю, что постоянное обращение продлевает жизнь временного местного жителя. Теперь я спрашиваю себя, можно ли распространить это уместность на цепочку временных объектов, то есть можно ли безопасно определить:
std::string const& foo = aBar.getTemporaryObject1().getTemporaryObject2();
Я чувствую, что, так как первый метод aBar.getTemporaryObject1()
возвращает уже временный объект, право собственности не сохраняется для aBar.getTemporaryObject2()
,
Продление срока действия применяется только тогда, когда ссылка напрямую связана с этим временным.
Например, инициализация другой ссылки из этой ссылки не делает другого расширения.
Тем не менее, в вашем коде:
std::string const& foo = aBar.getTemporaryObject1().getTemporaryObject2();
Вы напрямую связаны foo
к возвращаемому значению getTemporaryObject2()
, предполагая, что это функция, которая возвращает значение. Не имеет значения, была ли это функцией-членом другого временного объекта или чего-то еще. Так что этот код в порядке.
Время жизни объекта, возвращаемого getTemporaryObject1()
не расширяется, но это не имеет значения (если getTemporaryObject2
Возвращаемое значение содержит ссылки или указатели на этот объект, или что-то, но так как это, очевидно, std::string
не мог)
std::string const& foo = aBar.getTemporaryObject1().getTemporaryObject2();
является действительным (TemporaryObject2
продлен, но не TemporaryObject1
)
std::string const& foo = aBar.getTemporaryObject1().member;
также действует (TemporaryObject1
продлен).
но
std::string const& foo = aBar.getTemporaryObject1().getReference();
недействительно: время жизни TemporaryObject1
не продлен.
Название вводит в заблуждение. Вы не должны возвращать ссылку на местный объект как указано в названии, но временный объект (возврат по значению).
string & foo1()
{
string tmp("hello");
return tmp;
}
string foo2()
{
string tmp("hello");
return tmp;
}
void foo3()
{
const string & r1 = foo1(); // crashes later.
const string & r2 = foo2(); // Ok, object lives in scope of foo3.
}
второй вызов — не что иное, как:
const string & r2 = string("hello");
Пока функции возвращаются по значению, стек вызовов не имеет значения. Время жизни последнего объекта будет расширено до времени жизни области его ссылки.