вернуть константную ссылку на подкласс

Я знаю, что возвращение константной ссылки временного объекта — это нормально! (как этот пример 🙂

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 .. да .. но это предупреждение довольно ужасно ….

Благодаря вам, я знаю, вижу мою ошибку … но я хотел бы знать некоторые другие вещи об этом …

Когда это выполняется, что именно в стеке происходит?

6

Решение

Привязка ссылки к временному объекту продлевает время существования временного … кроме случаев, когда это не так. §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() функции должны возвращать указатель на выделенную кучу копию.

12

Другие решения


По вопросам рекламы [email protected]