简体   繁体   English

如何使具有包含唯一指针的成员变量的类可复制分配?

[英]How can I make a class, with a member variable that contains unique pointers, copy assignable?

I have a class (PlayerCharacter) that contains a map which in turn contains unique pointers. 我有一个包含映射的类(PlayerCharacter),该映射又包含唯一的指针。 I have another class (Party) which should contain multiple instances of this first class. 我有另一个类(聚会),其中应包含该第一个类的多个实例。 When I try to implement a constructor for Party that takes an instance of PlayerCharacter and copies it into the first element of a vector I get multiple errors (using g++) which are too long to put into this question. 当我尝试为Party实现一个构造函数,该构造函数采用PlayerCharacter的一个实例并将其复制到向量的第一个元素中时,出现多个错误(使用g ++),这些错误的时间太长了,无法提出这个问题。

I believe the error arises because BaseCharacter, and therefore PlayerCharacter, is not copy-assignable due to the unique pointers. 我相信会出现该错误,因为BaseCharacter以及PlayerCharacter由于唯一的指针而无法复制分配。 How can I implement a complete copy constructor for this class? 如何为此类实现完整的副本构造函数?

MCVE below 下方的MCVE

#include <map>
#include <utility>
#include <memory>
#include <vector>

enum class EQUIPMENT_SLOT {
    HEAD
};
class WeaponItem {};
class ClothingItem{};
class BaseCharacter {
    private:
        std::map<EQUIPMENT_SLOT, std::pair<std::unique_ptr<WeaponItem>, std::unique_ptr<ClothingItem>>> _equipment;
};
class PlayerCharacter : public BaseCharacter {};
class Party {
    private:
        std::vector<PlayerCharacter> _party_members;
    public:
        // Addition of this constructor causes errors to appear
        Party(PlayerCharacter player){
            this->_party_members.clear();
            this->_party_members.push_back(player); // This line is the problem - commenting it out compiles fine
        };
};
int main(){
    return 0;
}

If you're holding items in a unique_ptr, it normally implies that you're not looking to copy them. 如果您将项目保留在unique_ptr中,则通常意味着您不想复制它们。 If you want to copy them you'll have to provide the mechanism to do so: 如果要复制它们,则必须提供执行此操作的机制:

struct my_thing {
};

using my_thing_ptr = std::unique_ptr<my_thing>;

struct my_container
{
  my_container() {}

  // the presence of _thing will implicitly delete copy constructor 
  // and copy operator so we need to provide them. 
  // Since we're defining copy operators, these will disable 
  // the automatic move operators so we need to define them too!

  my_container(const my_container& rhs)
  : _thing { rhs._thing ? new thing { *(rhs._thing) } : nullptr }
  {}

  my_container(my_container&& rhs) = default;

  my_container& operator=(const my_container&& rhs) {
    auto tmp = rhs;
    swap(tmp, *this);
    return *this;
  }

  my_container& operator=(my_container&& rhs) = default;

  // and an implementation of swap for good measure
  void swap(my_container& other) noexcept {
    using std::swap;
    swap(_thing, other._thing);
  }


  my_thing_ptr _thing;

};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM