我正在尝试制作地图,在其中我将团队作为多态性作为值的员工的关键和向量。某些数据将来将从文件中加载,用户将能够随时添加新的团队和员工。
这是我想出的地图:
std::map<std::unique_ptr<Team>, std::unique_ptr<std::vector<std::unique_ptr<Employee>>>> teams;
这是我尝试添加新团队和成员的一些测试代码:
bool Company::addTeam(const std::string & projectName)
{
teams.emplace(std::unique_ptr<Team>(new Team(projectName)), std::unique_ptr<std::vector<std::unique_ptr<Employee>>>(new std::vector<std::unique_ptr<Employee>>()));
for (std::map<std::unique_ptr<Team>, std::unique_ptr<std::vector<std::unique_ptr<Employee>>>>::iterator it = teams.begin(); it != teams.end(); ++it) {
std::cout << it->first.get()->getProjectName();
it->second.get()->emplace_back(std::unique_ptr<Employee>(new Programmer("David", "Beckham", "9803268780", "Djoe Beckham", Employee::LevelThree, projectName)));
std::cout << "n" << it->second.get()->at(0)->toString();
}
return false;
}
代码运行良好,无法打印员工数据,但在关闭应用程序后,它会引发异常,Visual Studio 打开delete_scalar.cpp并在以下代码处触发断点:
void __CRTDECL operator delete(void* const block) noexcept
{
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK); // break point
#else
free(block);
#endif
}
我试图找出我做错了什么以及如何解决它。如果与问题有关,我为所有员工类提供了空析构函数。如果我的想法看起来很愚蠢,并且有更简单的方法来实现我的目标,请告诉我。提前谢谢。
在设计方面,一个人可以同时在不同的团队中扮演多个角色。它可以是另一个类Role
将一个人链接到一个团队。不过,两个团队、任何角色在概念上都没有自己的人对象,因此Role
可以使用普通指针将Person
与Team
联系起来。
如果你在一个班级中没有问题,你的想法可能会奏效。 由于缺少零件,很难说。
但是,这不是要走的路!
映射旨在按值处理索引。一个典型的用例是找回具有已存在键的项目。当然,您可以使用指针作为键,但指针将充当一种 id,而无需任何多态操作。
另一方面,unique_ptr
旨在确保唯一的所有权。 因此,每个指针值仅存在一个唯一副本。 这使得它很难用作映射值:
auto team2 = make_unique<Team>();
teams [team2] = make_unique<vector<unique_ptr<Employee>>>(); // doesn't compile
上面的代码无法编译,因为team2
是一个unique_ptr
,无法复制到索引参数中。使用它来搜索或插入项目,需要移动它:
teams [std::move(team2)] = make_unique<vector<unique_ptr<Employee>>>(); //compiles
assert (team2); // ouch
但是一旦移动,unique_ptr
值就不再在team2
现在为空,因为唯一指针位于映射键中并且它是唯一的。这意味着您将永远找不到添加的团队。
更好的选择?
如果你想真正使用多态指针作为映射键,你至少应该使用shared_ptr
,以便代码中可以存在多个副本。但我建议你只使用值作为键
现在到地图的值部分。 对vector
进行unique_ptr
没有任何好处:向量本身不是多态的,并且向量被很好地设计用于复制,移动等。 此外,即使对于非常大的载体,sizeof(vector<...>)
也很小。
如果您希望地图中的矢量拥有Employees
,请使用vector<unique_ptr<Employee>>
,如果您打算共享矢量的内容,请使用vector<shared_ptr<Employee>>
。