开发者

Defining a map with a structure inside it

I have a structure like

struct category 开发者_开发技巧{
    int id,newID;
    std::string name;
};

and a map like

std::map<std::string, category> categories;

is it safe to insert details into the map like

category x = {1,2,"Name"};
category y = {2,3,"Mike"};
categories["FIRST"]=x;
categories["SECOND"]=y;

or should i declare the map like

std::map<std::string, category*> categories;

and make structure pointers and insert it? which is safer?


What do you mean by safer? Both methods are just fine. When using the second way you must make sure to delete your category objects. On the first one they are deleted automatically when you delete your map.

The first one is slower if you need to pass the objects a lot around since you will be making copies. The second one would just copy pointers.

So it's up to you to decide which one fits your needs.


If you mean safety from resource leaks, in your particular example the first variant is perfectly safe.

If you use pointers, you will probably want to create the instances on the heap, which means manual memory management, which is prone to errors.

The only catch the second solution could have (in terms of security) is that objects need to be copyable. If the object manually manages any resources, you have to make sure that your copy-constructor and assignment-operator is implemented correctly.


Your question cannot really be answered without more context.

A naive answer might be "inserting the structures themselves is safer, because you don't have to worry about memory leaks". However, such an answer isn't really satisfactory.

To reach a better answer, you have to consider several factors:

  1. Is your struct supposed to be copyable? In other words, does it make sense in your application domain to have multiple copies of the same structure? If not, you should go with pointers.
  2. Your struct, in its current form, is copyable and has deep copy semantics. Is there a realistic possibility that in the future you will add members to it that will cause the deep copy semantics to break? If so, you will be forced to deal with this one way or another. This is related to the previous item, in that the copyability and copy semantics of your struct should influence your decision.
  3. Is your map likely to have lots of entries? Is it likely to have lots of entries where the keys differ but the values do not? In this case, using pointers will result in memory savings.


That's fine [your first example]. That's how you should do it.

You should only introduce indirection and dynamic allocation [your second example] when you really have to, as then you have to manage object lifetime and it's more error-prone.


I would wrap the category objects in a smart pointer and store the smart pointer. It is less heavy than storing the full object, allows access to the real object, and will automatically clean itself up.


Here are my notes on how to make this code safer:

  1. I would create a constructor for the struct category:

    struct category {
        category( int id, int newID, const std::string& name) : 
            id(id), newID(newID), name(name) {}
        int id,newID;
        std::string name;
    };
    

    This give you a chance not to break your code by changing the order of id and newID in structure, for instance. Now you can initialize it as categories["FIRST"]=category(1, 2, "Name");

  2. I would use smart pointers instead of plain pointers:

    std::map<std::string, boost::shared_ptr<category> > categories;
    
  3. std::map<std::string, category> is Ok too, but it will copy the category objects. If they are big enough this could be a performance issue.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜