std::map iteration
Okay, I'm using an std::map to store image pointers that are associated with id numbers. So, if you reference "1" it will reference the image that is associated with "1".
It is part of a class and I want to have a method that will free all the images from memory. The way that it is now, someone could have image "1" and image "5".
If it were an std::vector, I could just use a for loop to cycle through until the iterator was larger than the size of the vector, but I'm not sure that this is the case with a map, because you reference the item by it's association key, not it's number in the list.
So... I don't think I worded this post too well, but basically, how can I cycle through an std::map without using the "key" value, but instead, just iterate through all the items?
By using iterators, a concept that is common to all the SC++L's containers, and is very important for the generic algorithms and such. Iterators act a lot like pointers, in that you can dereference them (* or ->) to get what they refer (point) to. (In the case of std::map and std::multi_map, the container actually contains a set of std::pair<key, value>, rather than just values, so you dereference it and access first to get the key, or access second to get the value.)
However, I would recommend using some form of smart pointers (perhaps boost::shared_ptr) instead of using raw pointers. Then all you need to do is remove elements from the map, and never explicitly delete them. Much nicer that way.
std::map<std::string, image*> imageMap;//fill in imageMap with images...//then to erase everything:std::map<std::string, image*>::iterator imageIterator;for (imageIterator = imageMap.begin(); imageIterator != imageMap.end(); ++imageIterator){ delete imageIterator->second;}imageMap.clear();
However, I would recommend using some form of smart pointers (perhaps boost::shared_ptr) instead of using raw pointers. Then all you need to do is remove elements from the map, and never explicitly delete them. Much nicer that way.
Iteration is done with iterators. Hence the name. [wink]
All containers in the C++ standard library supply iterators.
So basically, you'd do something like this:
for (<type of your map>::iterator it = mymap.begin(); it != mymap.end(); ++it){
// Do stuff here
}
That works for maps, strings, vectors, sets and whatever other container you can think of.
All containers in the C++ standard library supply iterators.
So basically, you'd do something like this:
for (<type of your map>::iterator it = mymap.begin(); it != mymap.end(); ++it){
// Do stuff here
}
That works for maps, strings, vectors, sets and whatever other container you can think of.
How to iterate over a std::container?
Why, using an iterator of course [smile].
Or we could use boost::shared_ptr:
Why, using an iterator of course [smile].
typedef std::map<int,SomeType*> SomeTypeMap;SomeTypeMap someTypeMap;addStuffToMap(someTypeMap);for( SomeTypeMap::iterator it = someTypeMap.begin() ; it != someTypeMap.end() ; ++it ){ delete it->second;}someTypeMap.clear();
Or we could use boost::shared_ptr:
typedef std::map<int,boost::shared_ptr<SomeType> > SomeTypeMap;SomeTypeMap someTypeMap;addStuffToMap(someTypeMap);someTypeMap.clear();
with an iterator of course!
I believe this is the syntax:
edit: Jinx (for rip-off)
You guys are fast
I believe this is the syntax:
std::map<int, std::string> lookUpTable;// fill the look up tablefor(std::map<int, std::string>::iterator i = lookUpTable.begin(); i != lookUpTable.end(); ++i){ // do stuff}
edit: Jinx (for rip-off)
You guys are fast
you can do it with normal iterators, its just that the values are going to be a std::pair, in your case I guess std::pair<std::string, Image*>, I prefer to use stl algorithms for stuff like this. here is an example using for_each:
Hopefully thats ok, I just typed it in, no testing ;)
DeleteImage can be made more general too with templates so if you need to do this often it can be reused.
[Edited by - rollo on May 6, 2007 4:28:31 PM]
// functor that deletes the second part of an image pair.struct DeleteImage { void operator() (MyClass::ImageMap::value_type p) { delete p.second; }};class MyClass {public: // or whatever it is you have, typedefs are nice so you dont // have to repeat yourself typedef std::map<std::string, Image*> ImageMap; ~MyClass() { // clean up all images std::for_each(images.begin(), images.end(), DeleteImage()); }private: ImageMap images;};
Hopefully thats ok, I just typed it in, no testing ;)
DeleteImage can be made more general too with templates so if you need to do this often it can be reused.
[Edited by - rollo on May 6, 2007 4:28:31 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement