在析构函数中调用观察者是一种不良实践吗?

4

我有一个对象,在一组任务完成时发送信号。这些任务在线程池中独立执行。当一组任务全部完成时,我想向观察者发送通知。

本质上,这归结为引用计数方案。当引用计数(ref)等于0时,我发送通知。其中一个实现方法是利用boost智能指针(或任何引用计数的自动指针)。

class TaskCompletionNotifier {
  ~TaskCompletionNotifier() {
    _listener->notify();
  }

  setListener(listener);

  Listener _listener;
}

class Task {
  boost::shared_ptr<TaskCompletionNotifier> _notifier; 
}

我的问题是,在对象的析构函数中执行这个调用是否是不好的做法?

如果它可以抛出异常,那么这个问题最终就没有意义了。 - Bartek Banachewicz
正如Bartek所暗示的那样,这本身并不是一个坏主意,但是在执行析构函数时不能抛出异常。这将会终止您的程序。 - Jaywalker
当然,但这不是问题的重点,假设从异常处理的角度来看这是可以的。 - 4pie0
@lizusek 我宁愿不做任何假设。这就是为什么我在评论中提问,而不是发表答案的原因。 - Bartek Banachewicz
你总是做出很多假设,否则你就无法说出任何东西。 - 4pie0
显示剩余2条评论
2个回答

3

这是本质上有问题的吗?不是。

它是否会带来潜在的陷阱?是的。

确保您不允许任何异常逃离析构函数,并且最好确保_listener->notify()不会修改此对象的任何成员数据:如果它这样做,那么是安全可以接受的,但可能会令人困惑并/或破坏您的析构函数关闭逻辑。

除此之外,尽情使用吧。


我认为 OP 知道它的潜力,这也是他提出问题的原因,他也知道这并不本质上是坏的,这也是他提出问题的原因。 - 4pie0
@lizusek 那么...你是说这个问题的提问者已经知道了所有答案,我们应该忽略他吗? - Praetorian
不,我指的是@Lightness的评论“如果可以的话,这很好”。并不是非常有用。他的介绍也类似。 - 4pie0
@lizusek:我看不出来。原帖问这是否是一种不好的做法;我说不是。而你所做的是说“只要语言支持,就没问题”,这并没有回答原帖的问题,而是重新阐述了问题。 - Lightness Races in Orbit

-4

在析构函数中调用观察者模式是不好的编程实践吗?

不是不好的实践。

但这会带来许多潜在问题,所以请确保在不违反 C++规则(C++标准)的情况下执行。特别是:

  • 确保异常处理得当,以免异常从析构函数传播出去

2
这个如果没问题的话就可以了,但实际上并没有什么用处。 - Lightness Races in Orbit
你的回答似乎因为当前状态而被不公平地投票降低了评分,但从Lightness的评论来看,我猜原始版本没有包括异常吞噬部分,这使得它不值得一提,更别说是一个答案了。此外,你的编辑似乎直接从Lightness的答案中借用了短语。 - Praetorian
是的,它确实提到了异常从析构函数传播出去的问题。是的,因为只有答案的开头不同,所以我不想给任何人下降票的机会,并使用与他的答案相同的单词。显然,还有更多要考虑,不仅仅是答案本身。 - 4pie0
2
不,当时它根本没有提到任何异常。别撒谎。 - Lightness Races in Orbit
是的,确实是这样。即使它一开始没有被采纳,在编辑后大约10秒钟后就被采纳了,所以应该清除downvotes。我认为我的答案比你的更好,即使只考虑介绍部分。你的介绍包含的信息非常少。 - 4pie0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接