【问题标题】:adding static_pointer_cast<Derived> to a std::list<shared_ptr<Base>> causes pure virtual method called error将 static_pointer_cast<Derived> 添加到 std::list<shared_ptr<Base>> 会导致纯虚方法称为错误
【发布时间】:2019-04-24 13:53:41
【问题描述】:

我有这个基类

class Base {

    std::string nome;

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

我从中派生了这个 Directory 类

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&lt;Base&gt;(p)); 引起的,而terminate called recursively 是由p-&gt;parent = std::shared_ptr&lt;Directory&gt;(this); 抛出的。 使用childs.push_back(p) 可以正常工作,为什么? 它是否试图创建 Base 对象的实例?我可以使用基类的 shared_ptr 来管理派生类对象的列表吗?

【问题讨论】:

  • 您不能将*this 的所有权移交给shared_ptr

标签: c++ casting virtual shared-ptr


【解决方案1】:

您必须使用enable_shared_from_this 才能从this 创建shared_ptr

将你的类声明更改为 ...

class Directory : public Base, public std::enable_shared_from_this&lt;Directory&gt;

并将std::shared_ptr&lt;Directory&gt;(this) 替换为shared_from_this()。还要确保所有目录(包括根目录)都是使用共享指针构造的。

【讨论】:

  • parent 和 thisDirectory 是weak_ptr
  • @TonyRomero weak_ptr 是从 shared_ptr 构造的,所以这绝对没问题(这是你已经做过的)
猜你喜欢
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
  • 2018-07-03
  • 2012-11-04
  • 1970-01-01
  • 2021-05-14
  • 2010-11-24
  • 1970-01-01
相关资源
最近更新 更多