Значение ссылки и полиморфизм - PullRequest
1 голос
/ 03 июля 2019

Когда я запускаю следующий код, я получаю следующее аварийное завершение:

"чисто виртуальный метод с именем terminate вызван без активного исключения"

Я не понимаю, почему полиморфизм здесь не работает,Пожалуйста, кто-нибудь может мне помочь.

struct Base
{
    virtual void print()=0;
    virtual ~Base(){}
};

struct Derived: public Base
{
    void print(){cout << "this is Derived\n";}
};

struct Foo
{
    Foo(Base&& r): bref{r} {}
    void print(){
        bref.print();
    }
    Base& bref;
};

int main()
{
    Foo f{Derived()};
    f.print(); //it crashes here with above message
}

Ответы [ 2 ]

4 голосов
/ 03 июля 2019

Время жизни временного объекта Derived() продолжается до полного выражения Foo f{Derived()};.f.bref - это свисающая ссылка после этого.f.print() вызывает bref.print() с неопределенным поведением.

Foo{Derived()}.print(); было бы технически правильно определено, но сохранение ссылки на lvalue в объект, указанный в rvalue, переданный конструктору, вероятно, не имеет смысла.

1 голос
/ 03 июля 2019

bref - это свисающая ссылка, когда вы вызываете ее в Foo::print().Может быть, использовать unique_ptr, как это.

#include <iostream>
#include <memory>
struct Base
{
    virtual void print()=0;
    virtual ~Base(){}
};

struct Derived: public Base
{
    void print(){std::cout << "this is Derived\n";}
};

struct Foo
{
    Foo(std::unique_ptr<Base>&& r): bref{std::move(r)} {}
    void print(){
        bref->print();
    }
    std::unique_ptr<Base> bref;
};

int main()
{
    Foo f{std::unique_ptr<Derived>(new Derived)}; //or make_unique
    f.print();
}
...