If there is nothing that precludes it (polymorphism etc.), then I'd just use the simplest approach, namely std::vector<State>
. activeState
can still be a pointer (or an iterator).
Why not use std::vector<State> instead and not worry about storing pointers? It sounds like the list of states is fixed so any iterators will not be invalidated during the lifetime of the program.
Alternatively, I've found the Boost Pointer Container library to be useful for this sort of thing.
Since StateManager doesn't own contained objects, its contained type should be State*, and not smart pointer. It's OK to use auto_ptr in the main function, this is not related to the StateManager container.
In the case you want to have container which is responsible for contained objects lifetime, you can use smart pointer as contained type. But using auto_ptr is dangerous for this, since it has primitive ownership algorithm. It is better to use shared_ptr in such containers.
The way you use auto_ptr in the code you posted is not going to work.
std::auto_ptr<SomeState> test(new SomeState());
StateManager->registerState(test.get());
When the "test" variable goes out of scope, its' destructor will be called which will delete the SomeState object you just registered with StateManager. So now your StateManager is keeping a pointer to a deleted object, which will probably lead to a crash down the way.
Instead, you could look into using a reference counter smart pointer type, e.g. boost::shared_ptr.
auto_ptr s are supposed to manage the object's life time within a specified context. e.g.
void foo() { MyObject* pNewObject = new MyObejct;
// do something delete pNewObject; }
In the above function, if some exception occurred in //Do Something code, the object will not be free d and you will face memory leak in the code. We use Auto_ptrs in this kind of situations.
But it's not suitable for the following context (releasing an array). In the destructor of auto_ptr, it calls delete ptr; but with arrays we have to call delete[] ptr; If you use auto_ptr with array, memory leak will be occurred and leads to unexpected behavior void foo() {
unsigned char* pStream = new unsigned char[size]; ....
delete[] pStream; }
If you don't have much state and it's not so greedy for memory I recommend to use Singleton objects for your state classes. So you don't have to worry about memory management. State manager can handle the active state and the state objects but I don't think it's a good idea to Initialize the state object outside state manager and do the rest in statemanager and somewhere else. please ensure that the creation and destruction are unified