我有一个私人领域
std::map<std::string, std::multiset<GraphObject*>>* the_Map;
如何为其分配内存并插入 GraphObject?我必须使用 new 运算符吗?
the_Map = new map<string,multiset<GraphObject*>>;
我怎样才能插入一个新的 GraphObject?它是数据结构的一部分,我真的需要一个指向地图的指针。
我有一个私人领域
std::map<std::string, std::multiset<GraphObject*>>* the_Map;
如何为其分配内存并插入 GraphObject?我必须使用 new 运算符吗?
the_Map = new map<string,multiset<GraphObject*>>;
我怎样才能插入一个新的 GraphObject?它是数据结构的一部分,我真的需要一个指向地图的指针。
为什么要存储 a ::std:multiset
ofGraphObject *
有点晦涩,但让我们继续吧。
这是一个文档确实可以轻松回答的答案,但是对于 StackOverflow 来说毫无疑问太愚蠢了,所以...
the_Map = new map<string,multiset<GraphObject*>>;
这确实是您为地图分配内存的方式。对周围的事物有简单的指针通常不是一个好主意,但你坚持,这就是你的做法。这意味着您也必须delete
在某个时候记住它。而且您必须确保保存指针的类的复制构造做正确的事情(并且说正确的事情将相当复杂)。
你现在有一个有趣的问题。您multiset
在每个地图条目中存储 a 。幸运的是,当访问以前未知的键时,该多重集将自动创建并初始化为空。OTOH,您使用裸指针意味着您有异常安全问题。如果在此过程中的任何地方抛出异常,则可能会泄漏内存。所以你必须捕捉任何异常并清理你的对象:
GraphObject *tmp = new GraphObject;
try {
(*the_Map)[key].insert(tmp);
} catch (...) {
delete tmp;
throw;
}
您的问题是如此基本的事实使我质疑您关于需要使用指针的断言。而且我真的想知道您是否宁愿拥有 amultimap
而不是map
from string
-> multiset
。但是,您坚持数据结构的一般形式。所以上面是你如何使用它。
我还要说,这种数据结构大量使用裸指针是一个非常糟糕的主意。您必须编写一个非常复杂的函数来正确解构或复制整个混乱。
编辑:叹息凌晨 4 点对我自己永远不会创建的数据结构进行编码导致我编写了一些非常愚蠢的代码。现在的版本好多了。虽然这个答案真的比我的好得多。
如何为其分配内存并插入 GraphObject?
它根本不想成为指针;只需使地图本身成为类的成员,内存分配就会自动发生。
正确插入一个对象是相当繁琐的,因为你也在那里存储指针。如果它不需要是一个指针,那么存储对象会让你的生活更轻松。如果它确实必须是一个指针(例如,因为GraphObject
是一个多态基类),我建议存储智能指针:std::unique_ptr
,std::tr1::shared_ptr
或者boost::shared_ptr
如果你被困在过去。
如果你真的,真的因为某些疯狂的原因需要使用原始指针,那么最接近异常安全插入的可能是:
GraphObject * object = new Whatever(...);
try {
the_Map[key].insert(object);
} catch(...) {
delete object;
throw;
}
或者如果您不关心插入失败时内存泄漏的可能性:
the_Map[key].insert(new Whatever(...));
删除时也不要忘记删除每个对象;这不会自动发生。
我真的需要一个指向地图的指针。
不,你没有。但是,如果您真的相信自己做到了,并且想忽略每个人的建议,那么您将需要一张实际的地图来指向。我建议您将此地图设为该类的成员,以便自动管理其生命周期。
如果你真的想让维护代码的人生活困难,那么我想你可以分配一个new
. 在这种情况下,请记住在完成后将其删除;可能在类析构函数中。如果你这样做了,记住三法则并实现或删除复制构造函数和复制赋值运算符,因为默认实现会做错事。