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