对象被销毁时调用回调函数

时间:2015-05-27 03:49:14

标签: c++ exception c++11

我正在阅读很久以前写过的一些论坛帖子,并遇到这样的问题:

如何创建一个对象,以便可以向其传递回调函数,当对象被销毁时,总是会执行回调函数?

我知道这个回调函数应该放在析构函数中,因为RAII。有人发布了解决此问题的解决方案代码,如下所示

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)();
};

但不知怎的,我对这段代码感到不舒服。

  1. 由于经常建议不要在析构函数中使用throw,但至少在此代码中是否正常,因为整个trycatch块在析构函数内部?< / LI>
  2. 不知怎的,我觉得在析构函数中取消引用指针是不安全的,因为当已经抛出另一个异常时,指针指向的对象在堆栈展开期间可能处于无效状态。但是在这段代码中,指向的函数是一个成员函数,在析构函数中有检查这个指针,所以在这种情况下它是否完全正常?
  3. 有没有比此代码更好的解决方案?

1 个答案:

答案 0 :(得分:2)

规则不允许任何例外 逃避 析构函数。

析构函数可以接收异常,甚至抛出异常,前提是它们在析构函数方法结束之前被捕获。所以在结束之前抓住一切。

我发现在detor中取消引用指针没有错。它与任何其他方法相同,具有相同的风险。 (因此请提前计划,以免取消引用NULL或指针无效)。

你的代码看起来很不错。
我指出缺少虚拟dtor,并且根据细节,您可能希望成员完成 受保护的成员而不是私人