如何在vector <unique_ptr>中添加/删除?

时间:2017-05-26 13:30:34

标签: c++ c++11 vector smart-pointers

我使用unique_ptr代替shared_ptr,因为它不计算参考并且速度更快。您可以将其更改为shared_ptr。我的问题是如何正确地添加/删除智能指针的向量? 关键线在这里:

CEO->add(std::move(headSales));
CEO->remove(headSales);

代码:

#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include <iostream>
#include <vector>
#include <memory>
class Employee
{
protected:
    std::string name;
    std::string department;
    std::uint32_t salary;
    std::vector<std::unique_ptr<Employee>> subordinates;

public:
    Employee(std::string n, std::string d, std::uint32_t s) : name(n), department(d), salary(s)
    {}
    bool operator==(const Employee &e)
    {
        return name == e.name && department == e.department && salary == e.salary;
    }
    void add(std::unique_ptr<Employee> e)
    {
        subordinates.push_back(e);
    }
    void remove(const std::unique_ptr<Employee> e)
    {
        subordinates.erase(std::remove(subordinates.begin(), subordinates.end(), e), subordinates.end());
    }
    std::vector<std::unique_ptr<Employee>> getSubordinates() const
    {
        return subordinates;
    }
};
#endif  //EMPLOYEE_H


#include "Employee.h"


int main()
{
    std::unique_ptr<Employee> CEO = std::make_shared<Employee>("John", "CEO", 30000);
    std::unique_ptr<Employee> headSales = std::make_shared<Employee>("Robert", "Head Sales", 20000);
    CEO->add(std::move(headSales));
    CEO->remove(headSales);
}

2 个答案:

答案 0 :(得分:4)

您的代码不需要唯一或共享指针。

#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include <iostream>
#include <vector>
#include <memory>
class Employee
{
protected:
  std::string name;
  std::string department;
  std::uint32_t salary;
  std::vector<Employee> subordinates;

public:
  Employee(std::string n, std::string d, std::uint32_t s) : name(n), department(d), salary(s)
  {}
  bool operator==(const Employee &e) const
  {
    return name == e.name && department == e.department && salary == e.salary && subordinates == e.subordinates;
  }
  void add(Employee e)
  {
    subordinates.push_back(std::move(e));
  }
  void remove(Employee const& e)
  {
    subordinates.erase(std::remove(subordinates.begin(), subordinates.end(), e), subordinates.end());
  }
  std::vector<Employee> getSubordinates() const
  {
    return subordinates;
  }
};
#endif  //EMPLOYEE_H


#include "Employee.h"


int main()
{
  Employee CEO = {"John", "CEO", 30000};
  Employee headSales = {"Robert", "Head Sales", 20000};
  CEO->add(headSales);
  CEO->remove(headSales);
}

此外,您的==应该是const,并且应该比较subordinates。因为它现在是Employee的向量,所以递归调用==

答案 1 :(得分:2)

std::unique_ptr<Employee> CEO = std::make_shared<Employee>("John", "CEO", 30000);
     ^^^^^^                               ^^^^^^

这是错误的,因为共享指针不能转换为唯一指针。目前还不清楚您是否打算拥有共享或独特的所有权。

 CEO->remove(headSales);
 subordinates.push_back(e);

这些是错误的,因为您正在尝试复制唯一指针。但是,唯一指针不可复制 - 否则它们不会保持唯一。相反,您必须从原始指针移动:

subordinates.push_back(std::move(e));

首先使用唯一指针作为Employee::remove的值的参数是不明智的。更多关于以下内容。

std::vector<std::unique_ptr<Employee>> getSubordinates() const
{
    return subordinates;
}

这次你试图复制一个唯一指针的向量。问题仍然存在 - 指针不可复制。因为函数是const,所以无法移动向量。也许您打算简单地提供读取权限。这可以通过返回引用来实现:

 const std::vector<std::unique_ptr<Employee>>& getSubordinates() const
CEO->add(std::move(headSales));
CEO->remove(headSales);

您正在使用已经移动过的指针。唯一指针的所有权唯一地转移到add,因此在移动后使用它不再有意义。

正如我所提到的,使用唯一指针作为删除值的参数是没有意义的。为了拥有唯一的指针,你必须拥有该指针 - 唯一的。因此,矢量不可能拥有它。您可以改为引用向量中包含的指针,并使用:

void remove(const std::unique_ptr<Employee>& e)

CEO->remove(CEO->getSubordinates().back());
  

您可以将其更改为shared_ptr

嗯,那会更简单。将所有unique替换为shared,并删除该std::move,该程序将格式正确。

PS。您想要的std::remove位于您忘记包含的<algorithm>标题中。

PPS。我不清楚为什么员工应该拥有其他员工的所有权 - 独特或共享。我建议所有员工都拥有其他东西 - 比如说Company,员工只拥有非拥有的关联。我建议std::weak_ptr