为什么插入用户定义的析构函数需要用户定义的副本构造函数 [英] Why does the insertion of user defined destructor require an user defined copy constructor
问题描述
以下代码编译:
#include <vector>
#include <iostream>
#include <memory>
using namespace std;
class container
{
public:
container(){}
~container(){}
};
class Ship
{
public:
Ship(){}
//Ship(const Ship & other){cout<<"COPY"<<endl;}
//~Ship(){}
std::unique_ptr<container> up;
};
Ship buildShip()
{
Ship tmp;
return tmp;
}
int main(int argc, char *argv[])
{
return 0;
}
但是如果我们包含用户定义的析构函数〜Ship (){}
,只有在我们还包括用户定义的副本构造函数 Ship(const Ship& other){cout<< COPY< < endl;}
But if we include the user defined destructor ~Ship(){}
, the code will only compile if we also include the user defined copy constructor Ship(const Ship & other){cout<<"COPY"<<endl;}
简而言之:
编译:
Ship(){}
//Ship(const Ship & other){cout<<"COPY"<<endl;}
//~Ship(){}
编译:
Ship(){}
Ship(const Ship & other){cout<<"COPY"<<endl;}
~Ship(){}
不编译:
Ship(){}
//Ship(const Ship & other){cout<<"COPY"<<endl;}
~Ship(){}
为什么要插入用户定义的析构函数需要一个用户定义的副本构造函数,为什么在上面的示例中我们根本需要一个副本构造函数?
Why does the insertion of user defined destructor require an user defined copy constructor and why do we need a copy constructor in the above example at all?
我希望上面的示例中不需要复制构造函数,因为unique_ptr甚至无法复制。
I would expect that there is no copy constructor needed in the example above, as unique_ptr can not even be copied.
推荐答案
之所以对代码进行编译是因为 buildShip()
在返回<$ c $时会使用由编译器自动生成的move构造函数c> tmp 。添加用户声明的析构函数可防止编译器自动生成一个析构函数。例如,请参见此或这个问题。而且由于成员 up
std :: unique_ptr
而不能使用编译器生成的副本构造函数。并显式删除 unique_ptr
的复制构造函数。
The code gets compiled because buildShip()
would use the move constructor automatically generated by the compiler when returning tmp
. Adding user-declared destructor prevents the compiler from auto-generating one. E.g., see this or this questions. And the compiler-generated copy constructor can not be used because of the member up
which is std::unique_ptr
. And copy constuctor of unique_ptr
is explicitly deleted.
因此可以编译,因为显式要求编译器生成移动构造函数:
So this will compile, because the compiler is explicitly asked to generate the move constructor:
class Ship
{
public:
Ship(){}
Ship(Ship&&) = default;
~Ship(){}
std::unique_ptr<container> up;
};
这篇关于为什么插入用户定义的析构函数需要用户定义的副本构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!