C ++在定义或声明类析构函数时使用已删除的函数

时间:2018-02-10 14:59:05

标签: c++ list c++11 components entity

我试图建立一个真正基本的组件实体系统,到目前为止我已经成功了。我已经可以向实体添加任何类型的组件。但是,我正在努力为我的节点列表对象实现任何类型的析构函数(双链表以便于删除组件)。

基本上在我的系统中,一个单独的对象包含一个unordered_map(std实现),它将boost :: uuid作为一个键并保存一个T(模板)类型的列表。这就像一个unordered_multimap,但更容易递归访问等等(我个人不喜欢迭代器实现,因为我不能让它工作,没有实体泄漏到其他实体,但那只是我)。

无论如何,我试图制作析构函数的类是列表模板类。这是它的完整定义:

#ifndef LIST_H_INCLUDED
#define LIST_H_INCLUDED
#include "node.h"

template<class t>
class List:InstanceCounted<List<t>>
{
private:
    typedef Node<t> NodeT;
    std::unique_ptr<NodeT> head;
    void initHead(const t &data)
    {
        this->head=std::make_unique<NodeT>(data);
        this->head->setNext(nullptr);
        this->head->setPrev(nullptr);
    }
public:
    List()
    {}
    List(const t &data)
    {
        this->initHead(data);
    }
    NodeT* getHead()
    {
        return &*this->head;
    }
    void addNew(const t &data)
    {
        NodeT *last;
        try
        {
            last = &*this->head;
            while(last&&last->getNext())
            {
                last=last->getNext();
            }
            last->setNext(new NodeT(data));
            last->getNext()->setPrev(last);
        }
        catch(...)
        {
            if(!this->head)
            {
                this->initHead(data);
            }
        }
    }
    void removeFrom(const int id)
    {
        NodeT *last = &*this->head;
        register int i = 0;
        while(last&&last->getNext()&&i < id)
        {
            last=last->getNext();
            i++;
        }
        if(last==&*this->head)
        {
            this->head.reset(this->head->getNext());
        }
        else delete last;
    }

    void printListContents(){
        Node<t> *h = &*this->head;
        std::cout<<"---List<"<<typeid(t).name()<<"> start---"<<"\n";
        while(h){
            h->printNode();
            h=h->getNext();
        }
        std::cout<<"---List end---"<<"\n";
    }

    ~List(); //It doesnt matter if I define or declare this directly it 
             //always throws the same errors (+/- appropriate not found 
             //errors because of the missing code)
};

#endif // LIST_H_INCLUDED

以下是错误:

(omitted)\compiler\lib\gcc\mingw32\5.1.0\include\c++\bits\stl_pair.h|113|error: use of deleted function 'List<std::__cxx11::basic_string<char> >::List(const List<std::__cxx11::basic_string<char> >&)'|

(omitted)\entitysystem\list.h|6|note: 'List<std::__cxx11::basic_string<char> >::List(const List<std::__cxx11::basic_string<char> >&)' is implicitly deleted because the default definition would be ill-formed:|

(omitted)\entitysystem\list.h|6|error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Node<std::__cxx11::basic_string<char> >; _Dp = std::default_delete<Node<std::__cxx11::basic_string<char> > >]'|

(omitted)\bits\unique_ptr.h|356|note: declared here|

现在我明白这一点:

(omitted)\entitysystem\list.h|6|note: 'List<std::__cxx11::basic_string<char> >::List(const List<std::__cxx11::basic_string<char> >&)' is implicitly deleted because the default definition would be ill-formed:|

可能是问题的关键,但我不明白

  1. 它与析构函数有什么关系(我想是这样的 如果你做了暗示你想要使用的东西会发生 新标准,如实现移动构造器?)
  2. 为什么要特别要求构造函数?
  3. 我该如何解决?
  4. 我已将整个项目暂时上传到hastebin,以便您可以稍微玩一下。我觉得这个问题嵌套在系统中,所以我不知道我可以从项目中省略多少。如果你需要更小的东西请问。我确实排除了&#34; instanceCounted.h&#34;来自项目,因为它只是一个计算实例的模板类。如果你需要它我可以添加它

    无论如何,我希望你能帮助我。

    以下是项目:https://hastebin.com/ayiquxepic.cpp

    请提供反馈,因为我想改善自己的风格。

1 个答案:

答案 0 :(得分:0)

根据cppreference:

  

隐式声明的移动构造函数

     

如果没有为类类型提供用户定义的移动构造函数   (struct,class或union),以下所有内容均为真:

     
      
  • 没有用户声明的副本构造函数;
  •   
  • 没有用户声明的副本赋值运算符;
  •   
  • 没有用户声明的移动赋值运算符;
  •   
  • 没有用户声明的析构函数;
  •   
     

然后编译器将一个移动构造函数声明为其类的非显式内联公共成员,其签名为T :: T(T&amp;&amp;)。

定义析构函数后,还必须定义移动构造函数,以便使用它来代替复制构造函数。

当您在ComponentTable的addList函数中实例化std :: pair时,移动构造函数用于将其插入到std :: unordered_map中。定义析构函数意味着不再隐式声明移动构造函数,因此编译器会尝试使用已删除的复制构造函数。