为什么插入用户定义的析构函数需要用户定义的复制构造函数

new*_*ost 3 c++ destructor copy-constructor unique-ptr c++11

以下代码编译:

#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;
}
Run Code Online (Sandbox Code Playgroud)

但是如果我们包含用户定义的析构函数~Ship(){},那么只有在我们还包含用户定义的复制构造函数时,代码才会编译Ship(const Ship & other){cout<<"COPY"<<endl;}

简而言之:

编译:

Ship(){}
//Ship(const Ship & other){cout<<"COPY"<<endl;}
//~Ship(){}
Run Code Online (Sandbox Code Playgroud)

编译:

Ship(){}
Ship(const Ship & other){cout<<"COPY"<<endl;}
~Ship(){}
Run Code Online (Sandbox Code Playgroud)

不编译:

Ship(){}
//Ship(const Ship & other){cout<<"COPY"<<endl;}
~Ship(){}
Run Code Online (Sandbox Code Playgroud)

为什么插入用户定义的析构函数需要用户定义的复制构造函数,为什么我们在上面的例子中需要一个复制构造函数呢?

我希望上面的例子中不需要复制构造函数,因为甚至无法复制unique_ptr.

AMA*_*AMA 11

代码被编译,因为buildShip()它将使用返回时由编译器自动生成的移动构造函数tmp.添加用户声明的析构函数可防止编译器自动生成析构函数.例如,看到这个这个问题.和编译器生成的拷贝构造不能因为构件的使用upstd::unique_ptr.并且unique_ptr显式删除了复制构造.

所以这将编译,因为显式要求编译器生成移动构造函数:

class Ship
{
public:
    Ship(){}
    Ship(Ship&&) = default;
    ~Ship(){}
    std::unique_ptr<container> up;
};
Run Code Online (Sandbox Code Playgroud)