Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

call callback function when object is destroyed

I was reading some forum posts written long time ago and run into a problem like this:

How do you create an object such that you can pass a callback function to it, and when the object is destroyed the callback function is always executed?

I know that this callback function should be put in the destructor since RAII. And someone posted a solution code to this problem as following

class MyClass {
  public:
    MyClass(void (*cb)()) : done(cb) {}
    ~MyClass() {
      if (done) {
        try {
            (*done)();
        }
        catch (...) {
            // choice of exit, log, throw an alert to somewhere in the 
            //system, or ignore
        }
     }
   }
 private:
 void (*done)();
};

But somehow I don't feel comfortable with this code.

  1. Since it is often advised not to throw in the destructor, but is it OK here at least in this code since the whole try, catch block is inside the destructor?
  2. Somehow I feel that it is not safe to dereference a pointer in a destructor, since the object pointed by the pointer may be in an invalid state during stack unwinding when there is another exception already thrown. But in this code, the function pointed to is a member function and in the destructor there is checking on this pointer, so is it perfectly OK in this case?
  3. Is there any better solution than this code?
like image 416
Allanqunzi Avatar asked Nov 21 '25 13:11

Allanqunzi


1 Answers

The rule is not to let any exceptions escape the destructor.

Your destructor can receive exceptions, and even throw exceptions, provided they are caught before the end of the destructor-method. So just catch everything before the end.

I see nothing wrong with dereferencing a pointer in the dtor. Its the same as any other method, with the same risks. (so plan ahead so that you do not dereference NULL or an invalid pointer).

Your code looks pretty good to me.
I'd point out the lack of a virtual dtor, and depending on the details, you may want to make member done a protected member instead of private

like image 135
abelenky Avatar answered Nov 23 '25 03:11

abelenky



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!