tags:

views:

155

answers:

5
+3  A: 

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).

Philipp
+9  A: 

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.

Ferruccio
+1 for Boost pointer containers.
mskfisher
When using boost containers, would I just pass the auto_ptr as is to registerState() and change the parameter type to std::auto_ptr, or do I still pass it by using the .get() function?
John
You don't use auto_ptrs with boost::ptr_vector. You just hand it a naked pointer and the ptr_vector takes ownership of it.
Ferruccio
Thank you for clearing that up. I'll take a look at Boost Pointer Containers as you suggested.
John
+3  A: 

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.

Alex Farber
+1 Because there is no need to pay for either managing smart pointers or copying objects in this situation. Normal pointers are OK.
Tomek Szpakowicz
+1  A: 

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.

Haakon
Right now, the StateManager is deleted before the states since the states and the statemanager should be destructed at the same time even if this means invoking release() on the state auto_ptr's in main() -- right?
John
I'm not entirely sure what you mean, but if you're saying that the test variable in the code you posted will not go out of scope before the StateManager is deleted, then there is no problem and your approach should work just fine.
Haakon
+1  A: 

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

Sarath