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:
- 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. - 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 yourstruct
should influence your decision. - 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:
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
andnewID
in structure, for instance. Now you can initialize it ascategories["FIRST"]=category(1, 2, "Name");
I would use smart pointers instead of plain pointers:
std::map<std::string, boost::shared_ptr<category> > categories;
std::map<std::string, category>
is Ok too, but it will copy thecategory
objects. If they are big enough this could be a performance issue.
精彩评论