Я знаю, что возвращение константной ссылки временного объекта — это нормально! (как этот пример 🙂
class A {
public:
virtual const A& clone () { return (A()); }
virtual std::string name() const { return ("A"); }
};
Возврат временного объекта и привязка к константной ссылке
Если бы я хотел это сделать, все равно правильно:
class B : public A {
public:
virtual const A& clone () { return (B()); }
virtual std::string name() const { return ("B"); }
};
Я думаю, что да, но во время выполнения возвращенный объект все еще рассматривается как объект A (как в этом примере 🙂
main.cpp
#include <iostream>
#include <string>
int main() {
B bb;
A* aa = &bb;
std::cout << aa->clone().name() << std::endl;
}
выход
valgrind ./a.out
==14106== Use of uninitialised value of size 8
==14106== at 0x401BF9: main (main.cpp:8)
==14106== Uninitialised value was created by a stack allocation
==14106== at 0x401BF2: main (main.cpp:8)
B
Это B .. да .. но это предупреждение довольно ужасно ….
Благодаря вам, я знаю, вижу мою ошибку … но я хотел бы знать некоторые другие вещи об этом …
Когда это выполняется, что именно в стеке происходит?
Привязка ссылки к временному объекту продлевает время существования временного … кроме случаев, когда это не так. §12.2 [class.teven] / p5, выделение добавлено:
Временное, к которому привязана ссылка, или временное, которое является
полный объект подобъекта, к которому привязана ссылка
сохраняется в течение всего срока действия ссылки, кроме:
- Временная привязка к ссылочному элементу в конструкторе т е р-инициализатор (12.6.2) сохраняется до выхода из конструктора.
- Временная граница с опорным параметром в вызове функции (5.2.2) сохраняется до завершения строительства полное выражение
содержащий вызов.- Время жизни временной привязки к возвращенному значению в операторе возврата функции (6.6.3) не продлевается; временный
уничтожен в конце полное выражение в ответном заявлении.- Временная привязка к ссылке в новый инициализатор (5.3.4) сохраняется до завершения полного выражения, содержащего
новый инициализатор.
Дело в вопросе вы связали (std::string foo(); const std::string & s = foo();
) все в порядке; время жизни временного возвращается foo()
продлен до s
кончается. В вашем коде временная привязка связана с возвращаемым значением, и, согласно третьему пункту выше, его время жизни не увеличивается, и ваша функция возвращает висячую ссылку.
Обычно говоря, clone()
функции должны возвращать указатель на выделенную кучу копию.