views:

577

answers:

6
Callback* p = new Callback;
func(p);

If I want to delete the callback object, when and how to delete that?

If it gets deleted early, then the callback may be failed.

+17  A: 

The best solution for this is to used a smart pointer.
You initialize the pointer with the callback and pass it to the function. when the function or whatever process is done, the callback will be deleted automatically by the smart pointer.
A good smart pointer implementation is boost::shared_ptr<>

shoosh
If you need a shared pointer then use the tr1::shared_ptr implmentation offered by your compiler (assuming it is modern), otherwise use boost::scoped_ptr for RAII with next to no overhead.
Patrick
In this situation std::auto_ptr is a better smart pointer. You are then passing ownership of the callback object to the function.
Martin York
given that we know absolutely nothing about where this callback is going I would say that neither of these can be safely suggested.
shoosh
+1  A: 

You could have a increment/decrement count of when the callback is used. When it is used, increment the count, when its no longer used, decrement it. When it reaches 0 or -1 free it.

Daniel A. White
+1  A: 

The "caller-backer" object holding the callback (the one performing the calls back to it) may be the proper owner (deciding the callback's lifetime, and, in particular, using delete to do away with the callback object, holding it with auto_ptr, etc) if and only if its semantics are such as to let it determine when no further callbacks will ever be needed -- that's impossible to tell from such scant information as supplied in the question.

You may also need ways for the code that creates the callback (and passes ownership of it to the caller-backer) to explicitly ask the "caller-backer" to delete the callback object (and perform no more callbacks) when said code is the one determining that no more callbacks will ever be necessary.

Other answers mention smarter pointers than auto_ptr to make problems about "who owns this" disappear (boost's shared_ptr, hand-rolled reference counting, ...) -- that may be good if you're being forced to use C++ for other reasons but are really pining for a language with garbage collection, but, if you choose C++ specifically because it gives you full control on memory usage, then correctly determining object ownership and lifetime issues is not optional (and it can seriously optimize your resource usage, compared to any kind of more or less automated "garbage collection" -- that's only important when you do need to closely control your resource usage of course;-).

Alex Martelli
+1  A: 

Assuming that func() is the only function using that particular Callback object and that this code is always executed in the order where the Callback object is made, I would put it after func() is called. This way, if you have to edit func() you don't have to worry about where the Callback object gets deleted. It also ensures that all pointers have been emptied since func()'s pointer should have stopped existing when the function has finished, the only thing left to do is to delete the pointer left referencing it.

I apologize if my understanding of pointers in C++ is flawed and caused me to give an incorrect answer, I was always a little confused about that.

indyK1ng
+3  A: 

If the code is as trivial as you put it, meaning there's only one reference to the Callback pointer after func() is executed, I believe an auto_ptr will suffice:

std::auto_ptr<Callback> p(new Callback);
func(p.get());

This also assures that should func() throw an exception the memory will still be freed.

Idan K
Did you mean "func(p.get())"?
bk1e
yes, thank you.
Idan K
If you are not passing ownership to the function. This is silly. Just create a normal object and pass a pointer to! Callback p;func(
Martin York
+1  A: 

If your code is as simple as what you have written, and func() directly calls the callback at some point, then this should be sufficient:

Callback p;
func(&p);

However, if func() saves a reference or pointer to the callback elsewhere, you need to keep track of the lifetime of that reference.

bk1e