Hi all
Yet another thread from your truly... I'm just wondering how I would be able to build a map container so that the elements were placed on the free store instead of the stack? Or does that come as standard with a map container?
Cheers!
Hi all
Yet another thread from your truly... I'm just wondering how I would be able to build a map container so that the elements were placed on the free store instead of the stack? Or does that come as standard with a map container?
Cheers!
That comes with std::map.
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
Yes it is part of the standard library, however it's unclear whether the elements are being placed on the stack or in the free store? Pointers to data on the free store appear to be incompatable with map elements... unless someone can explain to me how it's done?!
Why?
Could you explain, how you would code up a map where the unknown amount of items is stored on the stack?
Do you know linked list? It's node based. The nodes are in the free store. Same for map.
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
"I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008
"the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010
lol I seem to have caused some confusion with this one...
Consider the following code:
OK, I have placed a comment where my confusion comes in. If this were a standard array, I would be able to place the address of pointer pCard into the element, therefore ensuring there is no memory leak when the pointer goes somewhere else. To make it clear in case I'm talking nonsense again!, this is what I wanted to do:Code:#include <map> #include "EOJ_card.h" using std::map; template <class T, class A> void RevealDeck (const map <T, A> & deck); typedef map<string, Card> deck; int main () { deck Attrition; Card *pCard = new Card ("Battle Master", 6, 6); Attrition[pCard->getName()]= *pCard; // surely this is copying the data instead of the address?? delete pCard; pCard = 0; cout << "Entire Deck:\n"; RevealDeck(Attrition); cout << Attrition["Battle Master"]; return 0; } template <class T, class A> void RevealDeck (const map <T, A> & deck) { for (map <T, A>::const_iterator ci = deck.begin(); ci!= deck.end(); ++ci) cout << ci-> second << "\n"; cout << endl; }
However when attempting to compile it this way, it returns a compiler error claiming it is unsuitable for conversion.Code:Attrition[pCard->getName()]= pCard;
In the above code it would appear the data at pCard is copied into the map container element - however this is not what I'm looking for, I'm looking to place the address of the data in. Is there any way this can be done?
Last edited by Know_Your_Role; 06-10-2009 at 12:54 AM.
You need a map of strings and pointers to cards. You can do that:
The trouble now is clearing all of the memory before the deck is destroyed (because then you'd lose the pointers with which you delete!). Use an auto_ptr, you say. But those don't have the right copy semantics! So it begins!Code:typedef map<string, Card*> deck;
Anyway, the above code is what you're looking for. Just remember to delete your cards before the deck goes out of scope.
"If you tell the truth, you don't have to remember anything"
-Mark Twain
I think you are going rather over-board here. Don't allocate things dynamically if you don't need to. In this case, is Card a polymorphic type, so you need to store pointers to Cards?
Code:typedef map<string, Card> deck; int main () { deck Attrition; string cardName("Battle Master"); Attrition[cardName]= Card(cardName, 6, 6); cout << "Entire Deck:\n"; RevealDeck(Attrition); cout << Attrition[cardName]; return 0; }
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
Code Monkey - what you're saying makes sense, thanks. However I would not say "use auto_ptr" - since I don't know what auto_ptr is lol.
How would you suggest the best way is to delete the elements? Could you not just use the same syntax you would to delete all the elements in a standard array? I'm quite new to using containers...
Cheers :-)
I think we're getting confused. Your current code stores Cards, not Card pointers. That seems correct. Unless Card is a polymorphic base class, which would be strange, then there is no reason to store the Cards indirectly by pointer.
Why mess around with dynamic memory when you don't have to?
Code://try //{ if (a) do { f( b); } while(1); else do { f(!b); } while(1); //}
Well there could be performance related reasons if card were large and you were copying it around a lot, however that may be minimal in this case.
These days I like use objects with reference counts and smart pointers to go with them for most objects with semi-long life spans. A lot of these types of issues simply vanish when you do this. The main thing you have to watch for is circular references which can be handled by the judicious use of regular pointers where they make sense. For instance in a tree you can use smart pointers with reference counted nodes and if you need parent pointes those can just be regular pointers.
Since a playing card, when it comes down to it, is just a number between 0 and 51, I really don't think there is any performance issue in copying cards.
My Card class would look like this (minus the other usual things, like comparison operators):
Code:class Card { public: enum Suit { Diamonds, Clubs, Hearts, Spades }; Card( Suit suit, int value ) : mValue( (int)suit * 13 + value ) { } Suit GetSuit() const { return (Suit)( mValue / 13 ); } int GetValue() const { return mValue % 13; } private: int mValue; };
Code://try //{ if (a) do { f( b); } while(1); else do { f(!b); } while(1); //}
The "Battle Master" bit leads me to believe that this isn't your standard 52 card deck.
But still, storing them by value is a better idea. This is not time-critical code here.
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
OK I see your point about passing by value. However, my concern is that I want the data that will be in the elements created on the free store, not the stack. Is that done as standard with map containers anyway or is there a particular syntax I need to use?