首页 文章

unique_ptr列表,用于派生模板类

提问于
浏览
1

我想创建一个 list<unique_ptr<Base>> listOfBaseUniquePtr . 这将能够给我两个:
1.独特的ptrs,和
2.多态性 . 我可以调用每个派生类的虚函数 .

有些东西对我不起作用 . 看看下面的代码示例:

#include <iostream>
#include <list>
#include <memory>

using namespace std;

class Base {
};

list<unique_ptr<Base>> listOfBaseUniquePtr;

template <typename T>
class Derived: public Base {

};

int main() {

    listOfBaseUniquePtr.push_back(new Derived<int>()); // <--- error
}

错误:

main.cpp:19:53:错误:没有匹配函数来调用'std :: list> :: push_back(Derived)'listOfBaseUniquePtr.push_back(new Derived()); // <--- error ^ main.cpp:19:53:注意:候选人是:/ usr / include / c /4.8/list:63:0中包含的文件,来自main.cpp:2:/ usr / include / c /4.8/bits/stl_list.h:1015:7:注意:void std :: list <Tp,Alloc> :: push_back(const value_type&)[with _Tp = std :: unique_ptr; _Alloc = std :: allocator std :: list <_Tp,_Alloc> :: value_type = std :: unique_ptr] push_back(const value_type& x)^ / usr / include / c /4.8/bits/stl_list.h:1015:7:注意:参数1从'Derived'到'const value_type&{aka const std :: unique_ptr&}'/ usr / include / c /4.8/bits/stl_list.h:1020:7没有已知的转换:注意:void std :: list <_Tp,_Alloc> :: push_back(std :: list <_Tp,_Alloc> :: value_type &&)[with _Tp = std :: unique_ptr; _Alloc = std :: allocator std :: list <_Tp,_Alloc> :: value_type = std :: unique_ptr] push_back(value_type && __x)^ / usr / include / c /4.8/bits/stl_list.h:1020:7:note :参数1从'Derived *'到'std :: list> :: value_type && {aka std :: unique_ptr &&}'make [2]没有已知的转换:[CMakeFiles / uniqueptr.dir / main.cpp.o]错误1 make [1]:[CMakeFiles / uniqueptr.dir / all]错误2 make:[all]错误2

我究竟做错了什么?

2 回答

  • 3

    如果你看一下 push_back() 的签名,你会看到有两个重载 . 一个需要 std::unique_ptr<T> const& ,另一个需要 std::unique_ptr<T>&& .

    表达式 new Derived<int>() 返回 Derived<int>* 类型;显然,这不是前面提到的类型;没有任何重载具有 Derived<int>* 参数 .

    你可以做两件事:

    更换

    listOfBaseUniquePtr.push_back(new Derived<int>());
    

    listOfBaseUniquePtr.push_back( std::make_unique<Derived<int>>() );
    

    或者,使用 emplace() 成员函数的 emplace() 族;这是一个例子:

    listOfBaseUniquePtr.emplace_back( new Derived<int> );
    

    如果要通过基类的指针删除从该基类派生的类,则您的基类应始终具有虚拟析构函数 . 您的基类定义应该是:

    class Base
    {
    public:
        virtual ~Base() = default;
    };
    
  • 1

    你应该使用std::make_unique

    listOfBaseUniquePtr.push_back(std::make_unique<Derived<int>>());
    

    也不要忘记向你的Base添加虚拟析构函数:

    virtual ~Base(){}
    

    否则〜如果使用基类指针销毁,则不会调用派生的构造函数 .

相关问题