如何使用STL映射

How to use STL map?

本文关键字:映射 STL 何使用      更新时间:2023-10-16

我有一个私有字段

std::map<std::string, std::multiset<GraphObject*>>* the_Map;

我如何为它分配内存并插入一个graphject ?我必须用新的接线员吗?

the_Map = new map<string,multiset<GraphObject*>>;

我如何插入一个新的图形对象?它是数据结构的一部分,我真的需要一个指向map的指针

我如何为它分配内存并插入一个graphject ?

它根本不想成为一个指针;只要将map本身设置为类的成员,内存分配就会自动进行。

正确插入对象是相当麻烦的,因为你也在那里存储指针。如果它不需要是指针,那么存储对象将使您的工作变得容易得多。如果它真的必须是一个指针(例如,因为GraphObject是一个多态基类),我建议存储智能指针:std::unique_ptr,或std::tr1::shared_ptrboost::shared_ptr,如果你被困在过去。

如果你真的,真的因为一些疯狂的原因需要使用原始指针,那么最接近异常安全插入的方法可能是:

GraphObject * object = new Whatever(...);
try {
    the_Map[key].insert(object);
} catch(...) {
    delete object;
    throw;
}

或者如果您不关心插入失败时内存泄漏的可能性:

the_Map[key].insert(new Whatever(...));

也不要忘记删除每个对象;这不会自动发生的。

我真的需要一个指向map的指针。

不,你没有。但如果你真的相信你有,并且想要忽略所有人的建议,那么你需要一个实际的地图来指向。我建议您将此映射作为类的成员,以便自动管理其生命周期。

如果你真的想让维护代码的人的生活变得困难,那么我想你可以用new分配一个。在这种情况下,记得在你完成后删除它;可能在类析构函数中。如果您这样做,请记住三法则,实现或删除复制构造函数和复制赋值操作符,因为默认实现将做错误的事情。

为什么要存储GraphObject *::std:multiset有点模糊,但让我们继续。

这是一个在文档中很容易回答的问题,但是对于StackOverflow来说没有什么问题是愚蠢的,所以…

 the_Map = new map<string,multiset<GraphObject*>>;

这确实是你为你的map分配内存的方式。一般来说,用指针指向周围的东西并不是一个好主意,但你坚持这样做,你就是这样做的。这意味着你必须在某个时候记住delete。您还必须确保持有指针的类的复制构造做了正确的事情(而所谓的正确的事情将相当复杂)。

你现在有一个有趣的问题。在每个映射条目中存储一个multiset。幸运的是,当访问之前未知的键时,这个multiset将自动创建并初始化为空。当然,使用裸指针意味着存在异常安全问题。如果在过程中的任何地方抛出异常,则可能会泄漏内存。所以你必须捕捉任何异常并清理你的对象:

 GraphObject *tmp = new GraphObject;
 try {
     (*the_Map)[key].insert(tmp);
 } catch (...) {
     delete tmp;
     throw;
 }

事实上,你的问题是如此基本,使我质疑你的断言需要使用指针。我真的很想知道你是否宁愿有multimap而不是string -> multisetmap。但是,你坚持数据结构的一般形式。以上就是如何使用它。

我还会说,这个数据结构大量使用裸指针是一个非常糟糕的主意。你必须编写一个非常复杂的函数来正确地解构或复制整个混乱。

编辑: 叹息凌晨4点在一个我永远不会自己创建的数据结构上编码导致我写了一些非常愚蠢的代码。当前的版本要好得多。虽然这个答案真的比我的好得多。