我正在尝试制作一个地图,在该地图中,我将以“团队”作为键,而“员工”的矢量则是多态的。将来某些数据将从文件中加载,用户将可以随时添加新团队和员工。
这是我想出的地图:
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
}
我正试图找出我做错了什么以及如何解决。如果与该问题有关,则我所有雇员类的析构函数都为空。如果我的想法看起来很愚蠢,并且有更简单的方法可以实现我的目标,请告诉我。预先感谢。
答案 0 :(得分:1)
在设计方面,一个人可以同时在不同的团队中扮演多个角色。可以是将人与团队联系起来的另一类Role
。这两个团队都没有,但是从概念上讲,没有角色拥有人对象,因此Role
可以使用普通指针将Person
与Team
链接起来。
答案 1 :(得分:1)
您的idea could work(如果您在一个班级中没有问题)。由于缺少零件,很难分辨。
但是,这不是可行的方法!
映射旨在按值使用索引。一个典型的用例是用一个已经存在的密钥找回一个项目。当然,您可以将指针用作键,但是指针将充当一种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
值将不再为空,因为唯一指针在map键中并且是唯一的,因此shared_ptr
现在为空。 这意味着您将永远不会找到增加的团队。
更好的选择?
如果您想真正使用多态指针作为映射键,则至少应使用unique_ptr
,以便代码中可以存在多个副本。但我建议您仅将值用作键
现在到地图的值部分。从vector
到sizeof(vector<...>)
没有好处:向量本身不是多态的,向量被很好地设计用于复制,移动等。此外,vector<unique_ptr<Employee>>
即使对于非常大的向量也很小。
如果要让地图中的矢量拥有 Employees
,请使用vector<shared_ptr<Employee>>
;如果要共享矢量的内容,请使用{{1}} 。