views:

227

answers:

9

Possible Duplicate:
Should objects delete themselves in C++?

In my application, I'm creating many objects that "own themselves" - in the sense that after they are created and told to "go," only the object itself can determine when it should be deleted.

For example, if I was writing a game, I might have multiple Enemy objects. Only the Enemy object knows when it should die.

As a result, I end up using delete this inside some of the member functions inside the Enemy object. Is this bad form? Is this something I should avoid, and if so, what is the correct way to handle this type of situation?

+5  A: 

The thing to be careful of is that if too many member functions have self-deletion as a side effect, it's easy to accidentally use a reference to the object after it's deleted.

One approach to avoid this is to defer the deletion - that is, put the object on a list, and from your game's main loop, delete everything on that list at the start/end of a tick.

bdonlan
oh, sounds like garbage collection! :-)
Tanktalus
@Tanktalus: Doesn't sound much like garbage collection to me, since the object is responsible for deleting itself when some logic is satisfied.
Paul Morie
@Paul: The original question didn't sound like GC. This answer does. Except that instead of scouring addresses to figure out what's not referenced anymore, you're adding yourself to the list of garbage to be collected at the next available cycle.
Tanktalus
So don't call it deleting itself, call it determining if it's "Killed" or not. You are right, you shouldn't delete the object until all referring objects have decided they are no longer interested in it.GC is critical to OO programming, it's just a matter of how it's implemented and who implements it.
Bill K
The fundamental attribute of GC is that the system automatically determines whether to delete an object based on structural information (that is, the graph of object references). The moment you need to explicitly tell it to delete something, even if that delete happens later, it's not GC.
bdonlan
A: 

Abstractly, I don't think you want an object deleting itself.

What you want to do is create a control structure that retrieves a SIGNAL or message from the object that it's time to "die", in this case, and the control structure will "delete" or take the particular necessary action on the object.

This way, you leave the control of the object existing or not on the control structure, and when everything has a centralized control unit, you prevent potential calls to deleted objects.

Also, remmeber to differentiate between a soldier "dying" as you say, and an object being actually "deleted" from memory. The dying portion, the object itself can accomplish by setting a flag, such as "dead = true." But the deletion of the object from memory should be accomplished by the control structure I'm referring to.

Sev
+3  A: 

Depends on the memory management strategy. There are cases that it really makes sense and it's the correct thing. For instance, in a reference counting system like COM, the object would do a delete this when the refcount gets down to zero.

Mehrdad Afshari
A: 

It seems odd to me, i myself would prefer someone or something getting rid of them. The fear of someone referencing the object is just terrifying to me. It also seems very possible for a "child" method to unknowningly destroy the object. When you return to a higher level method: you're operating on a non-existant object.

It sounds like you're inventing referencing counting, perhaps explicitely use the reference count pattern.

Or have the objects add themselves to a "to be destroyed" list - and you have yourself a garbage collection system.

Ian Boyd
A: 

As long as the Enemies manage all the references to them (eg. list of units, list of units in groups etc.) it's OK (and used quite often).

But if you want to be on the safer side, the Enemies should register themselves for some destruction routine run at some "safe spot" in the program execution (for an example, see QObject::deleteLater() in Qt.

jpalecek
A: 

You could use shared_ptrs to objects to have them automatically clean up when no references to them are available anymore.

Or call the destructor on the class.

sheepsimulator
A: 

To be honest you should try to stick away from that. Otherwise you might delete something that is used by something else and finish off by having a really odd result and probably some memory leak with it.

I think that the object should delete its resources in the destructor. Your class should use another class to know when the enemies are dead.

Partial
+3  A: 
For example, if I was writing a game, I might have multiple Enemy

objects. Only the Enemy object knows when it should die.

The enemy object may know when it enters a "dead" state, yes. But that is not necessarily the same as "the object should be deleted".

Think of all the other objects that may have a reference to it? They may at any time attempt to call a function on the Enemy object (say, TakeDamage()), and if the object has been deleted without informing them, you'll probably have a crash. How do they know that the Enemy they're shooting at is dead?

So the Enemy object knows when it is dead, but not when it should be deleted. It does not own itself.

Who does own it then?

The game world may be a good bet. When the enemy dies, it sends a message to the game world saying that it is dead, and the game world could then be responsible for making sure no one holds a pointer to it, and finally, when it is safe to do so, deleting the object.

jalf
A: 

The referring object(s) should do the deletion, and they should do so by asking the object if the conditions for deletion are met. One of the conditions (besides being eliminated from use in the game) are how many other objects still refer to the object. This is something that can be tracked with static reference counting. Generally, if you write it carefully, you might be able to build it in such a way that enemies are only tracked in one place in your game loop. That place will check collisions and other conditions, and when it's ready to delete the object it will not have to ask if deletion is okay because it knows it's the only client, and can safely dereference what it allocated.

dlamblin