简体   繁体   English

如何使用STL地图?

[英]How to use STL map?

I have a private field 我有一个私人领域

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

How can I allocate memory for it and insert a GraphObject? 如何为它分配内存并插入GraphObject? Do I have to use the new operator? 我必须使用新的运营商吗?

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

And how can I insert a new GraphObject? 我如何插入新的GraphObject? It's part of a datastructure and I really need a pointer to a map. 它是数据结构的一部分,我真的需要一个指向地图的指针。

Why you're storing a ::std:multiset of GraphObject * 's is a bit obscure, but lets roll with that. 你为什么要存储::std:multiset GraphObject *::std:multiset有点模糊,但让我们滚动它。

This is an answer that is really trivially answered by documentation, but there is no question too dumb for StackOverflow, so... 这是一个很简单的文档回答,但StackOverflow毫无疑问,所以......

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

That is indeed how you allocate memory for your map. 这确实是你为地图分配内存的方式。 It's generally not a good idea to have bare pointers to things lying around, but you insisted, and that's how you do it. 对于周围存在的东西只是指点一下通常不是一个好主意,但你坚持,这就是你如何做到的。 That means you will have to remember to delete it at some point as well. 这意味着您必须记住在某些时候delete它。 And you will have to make sure that the copy construct of the class that holds the pointer does the right thing (and said right thing will be fairly complicated). 而且你必须确保持有指针的类的复制结构做正确的事(并说正确的事情会相当复杂)。

You have an interesting problem now. 你现在有一个有趣的问题。 You are storing a multiset in each map entry. 您正在每个映射条目中存储multiset Fortunately this multiset will automatically be created and initialized to empty when a previously unknown key is accessed. 幸运的是,当访问以前未知的密钥时,将自动创建并初始化此多集。 OTOH, your use of bare pointers means that you have an exception safety problem. OTOH,你使用裸指针意味着你有一个异常安全问题。 It's possible to leak memory if an exception is thrown anywhere along the way. 如果在路上的任何地方抛出异常,则可能泄漏内存。 So you have to catch any exceptions and clean up your object: 所以你必须捕获任何异常并清理你的对象:

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

The fact your question is so basic makes me question your assertions about needing to use pointers. 你的问题是如此基本的事实让我质疑你需要使用指针的断言。 And I really wonder if you wouldn't rather have a multimap rather than a map from string -> multiset . 我真的不知道你会不会宁愿一个multimap ,而不是mapstring - > multiset But, you're adamant about the general form of your data structure. 但是,您坚持数据结构的一般形式。 So the above is how you'd use it. 所以上面就是你如何使用它。

I'll also say that this data structure's copious use of bare pointers is a pretty bad idea. 我还要说这个数据结构大量使用裸指针是一个非常糟糕的主意。 You'll have to write a pretty sophisticated functions to properly deconstruct or copy the whole mess. 你必须编写一个非常复杂的函数来正确地解构或复制整个混乱。

Edit : sigh Coding at 4am on a data structure I would never create myself led me to write some very stupid code. 编辑叹息编码在凌晨4点的数据结构我永远不会创建自己导致我写一些非常愚蠢的代码。 The current version is much better. 目前的版本要好得多。 Though this answer is really much better than mine. 虽然这个答案真的比我的好多了。

How can I allocate memory for it and insert a GraphObject? 如何为它分配内存并插入GraphObject?

It doesn't want to be a pointer at all; 它根本不想成为一个指针; just make the map itself a member of the class and memory allocation will happen automatically. 只需使地图本身成为类的成员,内存分配将自动发生。

Correctly inserting an object is rather fiddly, since you're storing pointers there too. 正确地插入一个对象是相当繁琐的,因为你也在那里存储指针。 If it doesn't need to be a pointer, then storing objects would make your life much easier. 如果它不需要是指针,那么存储对象将使您的生活更轻松。 If it really does have to be a pointer (eg because GraphObject is a polymorphic base class), I would recommend storing smart pointers: std::unique_ptr , or std::tr1::shared_ptr or boost::shared_ptr if you're stuck in the past. 如果它确实必须是一个指针(例如因为GraphObject是一个多态基类),我建议存储智能指针: std::unique_ptr ,或std::tr1::shared_ptrboost::shared_ptr如果你被卡住了以往。

If you really, really need to use raw pointers for some insane reason, then the closest you can get to an exception-safe insertion is probably: 如果你确实需要使用原始指针来解决一些疯狂的原因,那么最接近异常安全插入的可能就是:

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

or if you don't care about the possiblity of memory leaks on insertion failure: 或者如果您不关心插入失败时内存泄漏的可能性:

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

Also don't forget to delete each object when you remove it; 另外,不要忘记删除每个对象时删除它们; that won't happen automatically. 这不会自动发生。

I really need a pointer to a map. 我真的需要一个指向地图的指针。

No you don't. 不,你没有。 But if you really believe you do, and want to ignore everyone's advice not to, then you'll need an actual map to point to. 但如果你真的相信你这样做,并且想要忽略每个人的建议,那么你需要一个实际的地图指向。 I would recommend that you make this map a member of the class, so that its lifetime is managed automatically. 我建议您将此映射作为该类的成员,以便自动管理其生命周期。

If you really want to make life difficult for whoever maintains the code, then I suppose you could allocate one with new . 如果你真的想让维护代码的人生活困难,那么我想你可以用new分配一个。 In that case, remember to delete it when you've finished with it; 在这种情况下,请记住在完成后删除它; probably in the class destructor. 可能在类析构函数中。 And if you do that, remember the Rule of Three and implement or delete the copy constructor and copy-assignment operator, since the default implementations will do the wrong thing. 如果你这样做,请记住Rule of Three并实现或删除复制构造函数和复制赋值运算符,因为默认实现将执行错误的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM