C++ 在定义或声明 class 析构函数时使用已删除的函数
C++ Use of deleted function when defining or declaring class destructor
我正在尝试制作一个真正基本的组件实体系统,到目前为止我已经成功了。我已经可以将任何类型的组件添加到实体中。但是,我正在努力为我的节点列表对象(用于轻松删除组件的双链表)实现任何类型的析构函数。
本质上,在我的系统中,一个单独的对象包含一个 unordered_map(标准实现),它以一个 boost::uuid 作为键并包含一个 T 类型的列表(模板)。这就像一个 unordered_multimap 但更容易递归访问等。(我个人不喜欢迭代器实现,因为我无法在没有实体泄漏到其他实体的情况下让它工作,但那只是我)。
无论如何,class 我试图为列表模板 class 创建析构函数。这是它的完整定义:
#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.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:|
应该是问题的关键,但是我不明白
- 和析构函数有什么关系(我是这么想的
如果你做了一些暗示你想使用的事情就会发生
新标准就像实施移动构造函数?)
- 为什么它会特别需要那个构造函数?
- 我该如何解决?
我已经将我的整个项目暂时上传到 hastebin,所以你可以玩一下。我觉得这个问题嵌套在系统中,所以我不知道我可以从项目中省略多少。如果您需要更小的东西,请询问。我确实从项目中排除了 "instanceCounted.h",因为它只是一个计算实例的模板 class。如果你需要它,我可以添加它
无论如何我希望你能帮助我。
项目如下:https://hastebin.com/ayiquxepic.cpp
由于我想改进我的风格,还请提供反馈。
根据cppreference:
Implicitly-declared move constructor
If no user-defined move constructors are provided for a class type
(struct, class, or union), and all of the following is true:
- there are no user-declared copy constructors;
- there are no user-declared copy assignment operators;
- there are no user-declared move assignment operators;
- there are no user-declared destructors;
then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).
定义析构函数后,还必须定义移动构造函数,以便使用它代替复制构造函数。
当你在ComponentTable的addList函数中实例化一个std::pair时,移动构造函数用于将它插入到std::unordered_map中。定义析构函数意味着不再隐式声明移动构造函数,因此编译器会尝试使用已被删除的复制构造函数。
我正在尝试制作一个真正基本的组件实体系统,到目前为止我已经成功了。我已经可以将任何类型的组件添加到实体中。但是,我正在努力为我的节点列表对象(用于轻松删除组件的双链表)实现任何类型的析构函数。
本质上,在我的系统中,一个单独的对象包含一个 unordered_map(标准实现),它以一个 boost::uuid 作为键并包含一个 T 类型的列表(模板)。这就像一个 unordered_multimap 但更容易递归访问等。(我个人不喜欢迭代器实现,因为我无法在没有实体泄漏到其他实体的情况下让它工作,但那只是我)。
无论如何,class 我试图为列表模板 class 创建析构函数。这是它的完整定义:
#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.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:|
应该是问题的关键,但是我不明白
- 和析构函数有什么关系(我是这么想的 如果你做了一些暗示你想使用的事情就会发生 新标准就像实施移动构造函数?)
- 为什么它会特别需要那个构造函数?
- 我该如何解决?
我已经将我的整个项目暂时上传到 hastebin,所以你可以玩一下。我觉得这个问题嵌套在系统中,所以我不知道我可以从项目中省略多少。如果您需要更小的东西,请询问。我确实从项目中排除了 "instanceCounted.h",因为它只是一个计算实例的模板 class。如果你需要它,我可以添加它
无论如何我希望你能帮助我。
项目如下:https://hastebin.com/ayiquxepic.cpp
由于我想改进我的风格,还请提供反馈。
根据cppreference:
Implicitly-declared move constructor
If no user-defined move constructors are provided for a class type (struct, class, or union), and all of the following is true:
- there are no user-declared copy constructors;
- there are no user-declared copy assignment operators;
- there are no user-declared move assignment operators;
- there are no user-declared destructors;
then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).
定义析构函数后,还必须定义移动构造函数,以便使用它代替复制构造函数。
当你在ComponentTable的addList函数中实例化一个std::pair时,移动构造函数用于将它插入到std::unordered_map中。定义析构函数意味着不再隐式声明移动构造函数,因此编译器会尝试使用已被删除的复制构造函数。