【问题标题】:Can't initialize a vector of unique_ptr in class无法在类中初始化 unique_ptr 的向量
【发布时间】:2020-03-25 22:07:47
【问题描述】:

目前,我有两个班级,AiAction

我的班级Ai 有一个成员Action,名为_root

class Ai
{
  public:
    Ai();
    ~Ai();
  private:
    Action _root;
};

当我想用我的构造函数 Ai 初始化我的类 Action 时,就会出现问题。

Ai::Ai() : _root(Action(0, AI, 0, 0)) 
{
}

我的班级Action 和我的构造函数:

class Action
{
public:
  Action(int, Availability, int, int);
  ~Action();
  private:
    int _y;
    int _x;
    int _depth;
    Availability _type;
    vector<unique_ptr<Action>> _child;
};

Action::Action(int depth, Availability type, int y, int x)
{
  this->_y = y;
  this->_x = x;
  this->_depth = depth;
  this->_type = type;
}

问题恰好发生在vector&lt;unique_ptr&lt;Action&gt;&gt; _child;

当我创建一个对象Ai时,我的构造函数创建了一个具有默认值的对象Action,但它无法初始化unique_ptr的向量。

我的调试器给了我这个错误:

error: call to implicitly-deleted copy constructor of
  'std::__1::unique_ptr<Action, std::__1::default_delete<Action> >'
        ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);

有什么想法吗?

【问题讨论】:

  • 您复制构造了 _root 成员,但由于向量,类 Action 无法复制。它必须是moved。请阅读更多关于移动语义和move constructors

标签: c++ class pointers vector initialization


【解决方案1】:

您声明Ai 构造函数的方式是创建一个临时 Action 对象,然后将其复制到_root

解决方法很简单:

Ai::Ai() : _root(0, AI, 0, 0)

将构造函数参数直接传递给_root

无关,不需要使用this-&gt;来访问Action::Action中的成员变量。

【讨论】:

    【解决方案2】:

    Action 类不是用户定义的移动构造函数。它确实有一个用户定义的析构函数,可以防止自动生成移动构造函数。 Action 至少有一个无法复制的成员 (_child)。因此,Action 也没有复制构造函数。

    在 C++11 中,_root(Action(0, AI, 0, 0)) 只能在 Action 可以访问复制或移动构造函数时执行。它两者都没有。要解决此问题,您可以直接构造_root(参见1201ProgramAlarm 的答案),或者通过添加让编译器为您生成移动构造函数

    Action(Action&&) = default;
    

    See this example 用于 C++11


    在 C++17 中规则已经改变,由于mandatory copy/move elision_root(Action(0, AI, 0, 0)) 等同于_root(0, AI, 0, 0)。代码应该在没有可用的复制和移动构造函数的情况下编译(除非有其他原因导致编译失败)。

    See this example 用于 C++17

    【讨论】:

      猜你喜欢
      • 2021-12-08
      • 1970-01-01
      • 2016-12-30
      • 2017-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多