Jump to content
  • Advertisement
Sign in to follow this  
WarisSweet

C++ Object destruction

This topic is 4003 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

The problem I'm running into is that objects known about their own destruction before anything else, but I can not seem to find a way to delete them internally. Is there a clean way for an object in C++ to delete itself? At the moment I just set the destroyed property to true and then do a loop after updating objects to find those that are destroyed and delete them. Take into account that these objects are in a vector. In your experience have any of you run into this problem, or even better found a good solution?

Share this post


Link to post
Share on other sites
Advertisement

void MyClass::Die()
{
delete this;
}






You've got to be very careful doing this though - if any objects still have a pointer to the object after it deletes itself then you're guaranteed to have some crashes pop up!

[Edit] I just realised you said these objects are in a vector... Is that a vector of objects (vector<MyClass>) or a vector of pointers to objects (vector<MyClass*>)?

If the latter, you could do something like this:

class MyClass;
typedef std::vector<MyClass*> MyClassList;

class MyClass
{
private:
MyClass();//default constructor not usable

MyClassList& m_Owner;
protected:
MyClass( MyClassList& owner ) : m_Owner(owner)
{
m_Owner.push_back( this );//add self to list
}
virtual ~MyClass()
{//remove self from list
MyClassList::iterator i = m_Owner.find(this);
if( i == m_Owner.end() )
std::cout << "Error: already removed from list???" << std::endl;
else
m_Owner.erase( i );
}
public:
MyClass* CreateNew( MyClassList& owner )
{
return new MyClass( owner );
}

void Die() { delete this; }
};

MyClassList myVectorOfObjects;//create your vector
MyClass* pThing = MyClass::CreateNew( myVectorOfObjects );//adds a new MyClass to the vector
pThing->Die();//deletes the object, removes it from the vector
pThing = NULL;



[EDIT #2]
You might want to check out these links:
Is it legal (and moral) for a member function to say delete this?
What is the "Named Constructor Idiom"?

Share this post


Link to post
Share on other sites
Quote:
Original post by yahastu
Yeah..there is really no circumstance where an object should ever delete itself.


Intrusive reference counting. Ever try implementing a COM interface?

Share this post


Link to post
Share on other sites
Quote:
Original post by WarisSweet
set the destroyed property to true and then do a loop after updating objects... in a [container].


Instead, have the update function return a bool indicating living/dead status, and use it as a predicate with the erase/remove idiom:


bool Thing::update() {
// return true for dead objects
}

std::erase(std::remove_if(things.begin(), things.end(), std::mem_fun_ref(&thing::update)), things.end());

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman

std::erase(std::remove_if(things.begin(), things.end(), std::mem_fun_ref(&thing::update)), things.end());


I believe it's relevant to mention that the reason this will work without weird problems is because remove_if guarantees that the predicate is called exactly once per object [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
Quote:
Original post by Zahlman

std::erase(std::remove_if(things.begin(), things.end(), std::mem_fun_ref(&thing::update)), things.end());


I believe it's relevant to mention that the reason this will work without weird problems is because remove_if guarantees that the predicate is called exactly once per object [smile]


I was thinking about this earlier, and was about to ask. I take it this is a safe (and legal) method of updating tasks which are stored in a std::container, and may need to remove themselves?

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder
Quote:
Original post by ToohrVyk
Quote:
Original post by Zahlman

std::erase(std::remove_if(things.begin(), things.end(), std::mem_fun_ref(&thing::update)), things.end());


I believe it's relevant to mention that the reason this will work without weird problems is because remove_if guarantees that the predicate is called exactly once per object [smile]


I was thinking about this earlier, and was about to ask. I take it this is a safe (and legal) method of updating tasks which are stored in a std::container, and may need to remove themselves?


If the logic behind "may need to remove themselves" is sufficiently simple, yes*. If updating an object could influence some other object's decision on the matter, you may have problems. Especially if that other object appears earlier in the container.

* for standard library *sequences*. I wouldn't try it on a std::map if I were you.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Quote:
Original post by yahastu
Yeah..there is really no circumstance where an object should ever delete itself.


Intrusive reference counting. Ever try implementing a COM interface?


No I haven't implemented a COM interface, but I have done similar interfaces with reference counting for my own projects...and I would argue that intrusive reference counting is a bad paradigm, it would be better if the user pointer was not to the actual object itself..but to a container that holds the pointer, so that "obj->Release()" does not make the "obj" pointer invalid.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!