добавление static_pointer_cast <Derived>в список std :: listвызывает чисто виртуальный метод, называемый ошибкой - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть этот Базовый класс

class Base {

    std::string nome;

public:
    std::string getName() const;
    virtual int mType() const = 0;
    virtual void ls(int indent=0) const = 0;
};

из которого я получил этот класс Справочника

class Directory : public Base {

private:
    static std::shared_ptr<Directory> root;
    std::list<std::shared_ptr<Base>> childs;
    std::weak_ptr<Directory> parent;
    std::weak_ptr<Directory> thisDirectory;
    std::string nome;

protected:
    Directory(const std::string n);

public:
    static std::shared_ptr<Directory> getRoot();
    std::shared_ptr<Directory> addDirectory(std::string nome);
    std::shared_ptr<File> addFile(std::string nome, uintmax_t size);
    std::shared_ptr<Base> get(std::string name);
    std::shared_ptr<Directory> getDir(std::string name);
    std::shared_ptr<File> getFile(std::string name);
    void remove(std::string nome);

    int mType() const override;
    void ls(int indent=0) const override;
};

метод addDirectory

std::shared_ptr<Directory> Directory::addDirectory(std::string nome) {
    auto it = std::find_if(childs.begin(), childs.end(), [nome](std::shared_ptr<Base> p){return (p->getName()==nome);});
    if(it == childs.end()){
        std::cout<<"creating "<<nome<<" directory"<<std::endl;
        std::shared_ptr<Directory> p = std::shared_ptr<Directory>(new Directory(nome));
        childs.push_back(std::static_pointer_cast<Base>(p));
        p->parent = std::shared_ptr<Directory>(this);
        std::cout<<nome<<" created"<<std::endl;
        return p;
    }
    else {
        // todo gestione eccezione
        std::cout<<nome<<" already exists"<<std::endl;
        throw std::exception();
    }
}

напечатает этот вывод

pure virtual method called
creating root...
terminate called recursively
root created
creating alfa directory
alfa created

pure virtual method called вызвано childs.push_back(std::static_pointer_cast<Base>(p));, а terminate called recursively выброшено p->parent = std::shared_ptr<Directory>(this);. Использование childs.push_back(p) работает нормально, почему? Он пытается создать экземпляр базового объекта? Можно ли управлять списком объектов производного класса, используя shared_ptr для базового класса?

1 Ответ

0 голосов
/ 24 апреля 2019

Вы должны использовать enable_shared_from_this , чтобы создать shared_ptr из this.

Измените объявление класса на ...

class Directory : public Base, public std::enable_shared_from_this<Directory>

и замените std::shared_ptr<Directory>(this) на shared_from_this().Также убедитесь, что все каталоги (включая корневой) созданы с использованием общих указателей.

...