C++,函数指针与观察者模式

C++, functions pointers vs observer pattern

本文关键字:观察者模式 指针 函数 C++      更新时间:2023-10-16

几年前,在我了解C++之前,我曾与一位经验丰富的程序员同事讨论创建事件系统等问题。他似乎强调了传递函数指针的必要性,这样就可以进行回调来通知类状态变化等

然而,现在每当我需要实现某种事件系统时,我只需构造一个伪接口类,从中继承,并使用subscriber/observer模式来覆盖方法和分发事件。

前几天我在想,到目前为止,我很少需要使用函数指针,当然不适用于上述情况。我真正需要使用函数指针的唯一情况是,当与其他人的.dll接口时,它明确要求传递一个函数指针。

我什么时候应该使用函数指针而不是订阅者/观察者模式?

使用其中一种方法是好的还是坏的?(大概在某些情况下,观察者模式并不比函数指针更好)。

请有人分享一些见解好吗?如果能在这方面获得更多的经验会很好吗?(前面提到的一位同事转到了另一家公司,我们失去了联系)。我一直在这个问题上绞尽脑汁,想不出什么时候使用观察者模式和界面会更整洁。

谢谢!

一个我经常发现自己在写的课的例子(没有经过测试就写的,完全是我的想法,可能实际上不起作用):

class NotifierListener {
friend class Notifier;
private:
vector<NotifierListener*> mListeners;
protected:
void subscribe(NotifierListener* _subscriber) {mListeners->push_back(_subscriber);}
virtual void onNotification();
}
class Notifier : public NotifierListener {
private:
void doSomethingAndNotify() {
...
if (mListeners.size() > 0) {
for (int i = 0; i < mListeners.size(); ++i) {
mListeners[i]->onNotification();
}
}
}
}
class Something : public NotifierListener {
Something() { subscribe(this); }
void onNotification() {
cout << "I got notifiedn" << endl;
}
}

函数指针的效率要高一些。现在,您可以传递一个指向接口的指针。接口通常*包含指向vtable的指针。而vtable又包含函数指针。这是3个间接级别,参考位置较差。

[*]其他实现也是可能的,但有类似的开销。

wasthisfelp指出,继承和函数指针是实现观察者模式的两种方法。

使用函数指针(或者特别是类似C++11的std::function)的主要优点是增加了灵活性。观察类不需要实现接口,并且被调用的成员函数可以任意命名。您甚至可以调用一个独立的函数或一个不能或不想修改的对象的成员,以便它实现您的观察者接口。

另一方面,使用继承更简单、更直接。但除此之外,我想不出比函数指针方法有什么优势。

Observer Pattern中,侦听器是在接收事件时执行一些操作的实体。大多数时候,这些实体执行各自的工作,侦听事件,并根据它们接收事件时所处的状态调用可能不同的操作。所以更好的选择是具体的对象应该是监听器,因为对象有单独的状态。虽然使用纯函数(将使用函数指针调用)连贯/无缝地维护这些状态有点困难。