I want to store some object in an list. But poymorphism is needed. So I have to work with references. To avoid any memory leaks. I tried to use std::auto_ptr.
My container is:
class Layer : public GameObj, public std::list< std::auto_ptr<GameObj> > { public: virtual void draw(); virtual void update(); };
And this is where I try to create my str::auto_ptr and add it to the list:
OperationRaubvogel::OperationRaubvogel() : Game(320, 240, 0) { useKeyboard(); useTheme("sprites.png"); std::auto_ptr<GameObj> ship( new Ship ); push_back(ship); }
I get a long list of errors, pointing inside the stdlib. I'm new to the topic and have no idea how to go on.
Some additional infos:
OperationRaubvogel is a Game which is a Layer.
Ship is a GameObj.
Never put auto_ptrs in a container. Never, ever, ever. Why? Because auto_ptr does not have proper copy semantics and will be freed almost immediately.
Use boost::shared_ptr instead.
EDIT: In fact, don't use auto_ptr for anything. It's too easy to screw up. Use boost::shared_ptr or boost::scoped_ptr, depending on what you're doing.
EDIT2: Also, don't inherit from std::list.
My head hurts . Isn't there a way without an additional lib?
No. Besides, if you're serious about C++, you should get boost anyway. shared_ptr is header-only, so you don't need to worry about compiling anything. Just include and go.
Isn't there a way without an additional lib?
If you have recent compiler, then you might also have std::tr1::shared_ptr. With GCC 4.4 it is already std::shared_ptr in <memory>.
I have 4.3 . Is this standard C++?
shared_ptr is an addition to the standard library with C++0x.
shared_ptr is an addition to the standard library with C++0x.
I think you mean C++1x.
So it's going to be standard. Boost I'm comming.
Do you think it takes so long?
shared_ptr is an addition to the standard library with C++0x.
I think you mean C++1x.
There's still plenty of time for a finalization of C++0x: C++0a, C++0b, C++0c...
Do you think it takes so long?
It's been postponed till at least 2010.
I still don't understand why it's bad to inherit from standard containers directly.
Is-a vs. has-a. Your Layer is not a list of objects, it HAS a list of objects.
So it is a design question? No technical problems?
Don't underestimate design issues. Two things come immediately to mind:
You're also giving outside objects internal access to every object in the list -- they can delete and move around objects outside of the Layer's control, swap and erase, etc. all without proper or indeed any encapsulation.
As your class grows in functionality, you might want to add more stuff to the Layer -- another list of objects, perhaps -- and now you're in a really bloody weird spot, aren't you, with a list-in-a-list. Xzibit would be proud, but I won't.
EDIT: There is another very good reason you should consider in this particular case: standard containers do not have virtual destructors, but that class has virtual methods and so it must -- meaning you're opening yourself up for really unpredictable (undefined, actually) memory errors.
Here, you are even further complicating the issue by doing virtual multiple inheritance, which is honestly a mess that I only barely understand properly.
In the end, you have no reason to do this and it's both technically and design-wise a tremendously bad idea. Don't do it. I'd hate to phrase it this way, but if it helps to convince you, then: please, take it from someone who actually works in the industry with C++ on a daily basis. This is not a good idea.
I will change it. But at the moment I'm too lazy. It was too easy to to be correct . Programming can be really annoying sometimes. It's always more difficult then it seems.
One thing interests me. When I would add a virtual destructor to my layer class. Shouldn't this solve memory problems, except for referencing objects a std::list what I wouldn't do, anyway.
You should always have a virtual destructor if you think that the class has a possibility of being subclassed, and used as a pointer to your class (the parent). Considering that you can't really control the situation, sometimes programmers give every exposed class a virtual destructor.
The consequence of not doing this is that if your object is used on a polymorphic situation, your destructor may not be called when the object is destroyed, which is a bad plan. The consequence of having a virtual destructor when you don't need it is the cost of probably 4 bytes/object for a vtable pointer (and possibly none extra if RTTI is enabled).
I can't remember where I got this from but you don't have to install boost if you want a smart pointer.
I have used this reference count pointer quite a bit, and it does the job.
Edit:
It came from here.
smart pointers are notoriously difficult to get right (and perform well). Peter Dimov and others worked for some years on boost shared_ptr to get it right in the face of exceptions and threads, and weak_ptr as well.
Scanning that class above quickly for certain constructs, it doesn't seem to handle the exceptions. I'm not sure about out-of-memory conditions. So, if your code doesn't use threads or exceptions it will probably work perfectly.
I suppose my point is, using shared_ptr is the best way to go if you can, but this counted_ptr is probably good enough for something small and not for "production," and you don't need features like weak_ptr.
I decided to use boost. Thanks.
C++ just sucks because of these silly design questions. /arse