在类定义中涉及private unique_ptr时,在C++中引用初始化

Lun*_*oul 1 c++ memory-leaks memory-management

如何解释下面的编译错误?

#include <iostream>
#include <memory>
#include <vector>

using namespace std;

class A{
    unique_ptr<vector<short>> v;
public:
    A(){
        v = unique_ptr<vector<short>>(new vector<short>());
        cout << "A()" << endl;
    }
    A(const A& a) : A(){
        cout << "A(const A& a)" << endl;
    }
};

int main() {

    A a1; // prints A()
    A a2 = a1; // prints A() then A(const A& a)
    A& a3 = a1; // prints nothing
    a3 = a1; // compile time error: use of deleted function ‘A& A::operator=(const A&)

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

实际上,为什么A& a3 = a1好,a3 = a1不是?此外,正在使用哪个重载版本的operator =以及如何正确实现以避免此类问题?

vso*_*tco 6

在线

a3 = a1;
Run Code Online (Sandbox Code Playgroud)

你正在调用一个删除的operator=(记住unique_ptr是不可复制的).g ++为你吐出错误:

错误:使用已删除的函数'A&A :: operator =(const A&)'

而在线

A& a3 = a1; 
Run Code Online (Sandbox Code Playgroud)

没有复制,你只是初始化一个引用.

您可能想要移动指针,就像

a3 = std::move(a1); 
Run Code Online (Sandbox Code Playgroud)

遗憾的是,它不起作用,因为您显式声明了一个复制构造函数,这会阻止编译器生成默认的移动构造函数和赋值运算符.解决方案:声明移动赋值运算符并将构造函数移动为=default;,

A& operator=(A&&) = default;
A(A&&) = default;
Run Code Online (Sandbox Code Playgroud)

并且a3 = std::move(a1)上面的行将起作用.