如何使用STL地图?

时间:2013-01-09 14:26:53

标签: c++ memory-management maps

我有一个私人领域

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

如何为其分配内存并插入GraphObject? 我是否必须使用新操作符?

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

如何插入新的GraphObject? 它是数据结构的一部分,我真的需要一个指向地图的指针。

2 个答案:

答案 0 :(得分:2)

为什么你存储::std:multiset GraphObject *的{​​{1}}有点模糊不清,但让我们继续推行。

这是一个很简单的文档回答,但StackOverflow毫无疑问,所以...

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

这确实是你为地图分配内存的方式。对于周围存在的东西只是指点一下通常不是一个好主意,但你坚持,这就是你如何做到的。这意味着您必须在某些时候记住delete它。而且你必须确保包含指针的类的复制结构做正确的事(并说正确的事情会相当复杂)。

你现在有一个有趣的问题。您在每个地图条目中存储multiset。幸运的是,当访问以前未知的密钥时,将自动创建并初始化此多集。 OTOH,你使用裸指针意味着你有一个异常安全问题。如果在路上的任何地方抛出异常,则可能泄漏内存。因此,您必须捕获任何异常并清理对象:

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

你的问题是如此基本的事实使我质疑你需要使用指针的断言。我真的很想知道你是不是希望multimap而不是来自map的{​​{1}} - &gt; string。但是,您坚持数据结构的一般形式。所以上面是你如何使用它。

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

编辑叹息凌晨4点编码数据结构我永远不会创建自己导致我编写一些非常愚蠢的代码。目前的版本要好得多。虽然this answer确实比我好得多。

答案 1 :(得分:2)

  

如何为其分配内存并插入GraphObject?

它根本不想成为指针;只需使地图本身成为类的成员,内存分配将自动发生。

正确地插入一个对象是相当繁琐的,因为你也在那里存储指针。如果它不需要是指针,那么存储对象将使您的生活更轻松。如果它确实必须是一个指针(例如,因为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(...));

同样不要忘记在删除每个对象时删除它们;这不会自动发生。

  

我真的需要一个指向地图的指针。

不,不。但如果你真的相信你这样做,并且想要忽略每个人的建议,那么你需要一个实际的地图指向。我建议您将此地图设为该类的成员,以便自动管理其生命周期。

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