C++ 如何正确使用带有智能指针和自定义类的映射作为键和值

C++ 如何正确使用带有智能指针和自定义类的映射作为键和值,c++,dictionary,polymorphism,smart-pointers,C++,Dictionary,Polymorphism,Smart Pointers,我正在尝试制作一张地图,其中我将团队作为关键,员工的载体作为价值的多态性。将来将从文件中加载一些数据,用户可以随时添加新的团队和员工 这是我想到的地图: std::map<std::unique_ptr<Team>, std::unique_ptr<std::vector<std::unique_ptr<Employee>>>> teams; 我正试图找出我做错了什么,以及如何修复它。我为所有Employees类设置了空析构函数,如果

我正在尝试制作一张地图,其中我将团队作为关键,员工的载体作为价值的多态性。将来将从文件中加载一些数据,用户可以随时添加新的团队和员工

这是我想到的地图:

std::map<std::unique_ptr<Team>, std::unique_ptr<std::vector<std::unique_ptr<Employee>>>> teams;

我正试图找出我做错了什么,以及如何修复它。我为所有Employees类设置了空析构函数,如果这与问题有关的话。如果我的想法看起来很愚蠢,有更简单的方法来实现我的目标,请告诉我。提前感谢。

从设计角度来看,一个人可以同时在不同的团队中扮演多个角色。它可以是另一个类
角色
将个人链接到团队。但是,两个团队都没有角色在概念上拥有person对象,因此
role
可以使用普通指针将
person
链接到
team
您的,如果您的类中没有问题的话。由于缺少零件,很难分辨

然而,这不是一条路

映射意味着使用按值索引。一个典型的用例是找到一个已经存在密钥的项。当然,您可以使用指针作为键,但是指针将作为一种id,而不需要任何多态操作

另一方面,
unique\u ptr
设计用于确保唯一所有权。因此,每个指针值只存在一个唯一副本。这使得它很难用作贴图值:

auto team2 = make_unique<Team>(); 
teams [team2] = make_unique<vector<unique_ptr<Employee>>>();  // doesn't compile
但是一旦移动,
unique\u ptr
值不再位于
team2
中,该值现在为空,因为unique指针位于map键中,并且是唯一的这意味着您将永远找不到添加的团队

更好的选择?

如果您真的想使用多态指针作为映射键,那么至少应该使用
共享\u ptr
,这样代码中就可以存在多个副本。但我建议您仅将值用作键

现在转到地图的值部分。使
向量的
唯一\u ptr
没有任何好处:向量本身不是多态的,而且向量设计得很好,可用于复制、移动等。此外,即使对于非常大的向量,
sizeof(vector)
也很小


如果您希望地图中的向量拥有
员工
,请使用
向量
;如果您希望共享向量的内容,请使用
向量

你确定
std::map
或者甚至
std::multimap
都不能完成这项工作吗?除了覆盖
delete
操作符,你可以使用一个与
std::unique\u ptr
一起使用的自定义删除器。你显示的代码似乎不能解释你所问的错误。我怀疑是
团队
员工
的问题导致了此问题。可以肯定的是,您应该提供一个@πνταῥεῖ 我对这个问题的理解是,显示的
delete
正是Visual Studio声称发生错误的地方。我看不出问题在哪里声称他们写了这个
delete
。编辑:如果我
delete(char*)1,我会得到同样的结果到目前为止,您在调试问题方面做了哪些工作?在这样的情况下,当问题在清理中显现时,删除(或暂时注释掉)部分代码以缩小导致问题的代码区域非常有用。看到了吗,我想在团队类中移动向量,然后制作一个向量,你觉得这样行吗?@IvayloHristov,这样你就不用地图了?是的,这会有用的。
void __CRTDECL operator delete(void* const block) noexcept
{
    #ifdef _DEBUG
    _free_dbg(block, _UNKNOWN_BLOCK); // break point
    #else
    free(block);
    #endif
}
auto team2 = make_unique<Team>(); 
teams [team2] = make_unique<vector<unique_ptr<Employee>>>();  // doesn't compile
teams [std::move(team2)] = make_unique<vector<unique_ptr<Employee>>>(); //compiles
assert (team2); // ouch