временный c ++ — «чисто виртуальный метод»

Как я понимаю временные, следующий код должен работать, но это не так.

struct base
{
virtual~base() {}
virtual void virt()const=0;
};
struct derived:public base
{
virtual void virt()const {}
};

const base& foo() {return derived();}

int main()
{
foo().virt();
return 0;
}

Вызов virt () дает ошибку «чисто виртуальная функция называется». Почему это так, и что мне делать?

6

Решение

Кажется, вы ожидаете const ссылка на продление срока службы временного. Есть определенные ситуации, когда этого не происходит. Одна из таких ситуаций при возврате временного:

Второй контекст [в котором временные объекты уничтожаются в точке, отличной от конца полного выражения], — это когда ссылка связана с временным объектом. Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом подобъекта, к которому привязана ссылка, сохраняется в течение всего времени существования ссылки, за исключением:

[…]
  • Время жизни временной привязки к возвращенному значению в операторе возврата функции (6.6.3) не продлевается; временное уничтожается в конце полного выражения в операторе возврата.

Поскольку вызов функции-члена объекта возвращается foo() потребуется преобразование lvalue-в-значение, и объект недопустим (не получен из типа base), вы получите неопределенное поведение:

Если объект, на который ссылается glvalue, не является объектом типа T и не является объектом типа, полученного из Tили, если объект не инициализирован, программа, которая требует этого преобразования, имеет неопределенное поведение.

5

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

Вы возвращаете ссылку на временный, который разрушен когда функция заканчивается в конце return заявление, и вы получите неопределенное поведение.

Вы не можете вернуть какую-либо ссылку на временный и если вы возвращаете base по значению вы получите нарезку, поэтому, если вы действительно хотите, чтобы это работало, вы должны вернуть std::unique_ptr<base>,

8

Я не думаю, что вы можете вернуть ссылки на подобные объекты. Экземпляр производного () выходит из области видимости, как только возвращается функция foo (). Есть

base *foo() { return new derived(); }

а также

foo()->virt();

должно сработать.

3

Во время звонка объекта нет, локальный объект удален. Там не будет Vtable для просмотра. Пытаться:

base& foo() { return *new derived(); }
0

Ваш временный объект производного () расположен в стеке. Это может быть как-то связано с повышением качества объекта.

постоянная база& foo () {производная * d = новая производная (); возврат * d; }

Работает просто отлично, для меня.

0

Измените часть проблемы на это:

class A {
public:
const base &foo() { return d; }
private:
derived d;
};

Таким образом, время жизни производного объекта равно времени жизни А, и проблем не будет.

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