C++自己的观察者模式
C++ Own Observer Pattern
我正在设计一个观察器模式,它应该以这种方式工作:观察器调用EventDispatcher
的AddEventListener
方法,并传递一个字符串,该字符串是event
、PointerToItself和PointerToItsMemberMethod的名称
之后CCD_ 4发生在CCD_;它会查看订阅列表,如果有,则分配给该事件调用observer
的action
方法。
我来到这个EventDispatcher.h
小心包含一些伪代码。
有两个问题:
- 如何在
struct Subscription
中定义action
的类型 - 我走的路对吗
PS:不,我不会使用boost
或任何其他库。
#pragma once
#include <vector>
#include <string>
using namespace std;
struct Subscription
{
void* observer;
string event;
/* u_u */ action;
};
class EventDispatcher
{
private:
vector<Subscription> subscriptions;
protected:
void DispatchEvent ( string event );
public:
void AddEventListener ( Observer* observer , string event , /* u_u */ action );
void RemoveEventListener ( Observer* observer , string event , /* u_u */ action );
};
此标头在EventDispatcher.cpp
中实现如下
#include "EventDispatcher.h"
void EventDispatcher::DispatchEvent ( string event )
{
int key = 0;
while ( key < this->subscriptions.size() )
{
Subscription subscription = this->subscriptions[key];
if ( subscription.event == event )
{
subscription.observer->subscription.action;
};
};
};
void EventDispatcher::AddEventListener ( Observer* observer , string event , /* */ action )
{
Subscription subscription = { observer , event , action );
this->subscriptions.push_back ( subscription );
};
void EventDispatcher::RemoveEventListener ( Observer* observer , string event , /* */ action )
{
int key = 0;
while ( key < this->subscriptions.size() )
{
Subscription subscription = this->subscriptions[key];
if ( subscription.observer == observer && subscription.event == event && subscription.action == action )
{
this->subscriptions.erase ( this->subscriptions.begin() + key );
};
};
};
您可以定义一个Action类或传递一个lambda函数(C++11)。在后一种情况下,行动可以定义为
function<void (EventDispatcher*)> action;
您可以按照以下注册观察员
Observer * me = this;
observable->AddEventListener (this, "EventName", [me] (EventDispatcher* dispatcher) {
// code here; me is available
});
您可能应该使用智能弱指针将Observer存储在EventDispatcher中,这样您就不必关心取消注册了。
编辑:添加了以下示例(只有一个订阅是可能的,但应该说明这个想法——你必须小心,不要引用已经不存在的对象)
struct Observable {
std::weak_ptr<function<void (const Observable&)>> action;
void AddEventListener (std::weak_ptr<function<void (const Observable&)>> theAction) {
action = theAction;
}
void EventRaised () {
if (!action.expired ()) {
auto theAction = action.lock ();
(*theAction) (*this);
}
}
};
struct Observer {
...
void CallOnEvent (const Observable & observable) {
// do something
}
// field to store the action as long as it is needed
std::shared_ptr<function<void (const Observable&)>> action;
void ... {
auto me = this;
action = std::make_shared<function<void (const Observable&)>> (
[me] (const Observable& observable) {
me->CallOnEvent (observable);
}
);
// we could have as well used std::bind
observable.AddEventListener (action);
}
};
也许您应该创建一个由"users"派生的类:
class Action {
public:
friend class EventDispatcher;
virtual SomeResultType DoThis() = 0;
private:
/* Some common data */
};
只需将一些派生自类Action类型的变量传递给AddEventListener。当相应的事件被触发时,只需填写公共数据并调用DoThis()方法。
void EventDispatcher::DispatchEvent ( string event )
{
int key = 0;
while ( key < this->subscriptions.size() )
{
Subscription subscription = this->subscriptions[key];
if ( subscription.event == event )
{
subscription->action();
};
};
};
对于AddEventListener:
void EventDispatcher::AddEventListener ( Observer* observer , string event , Action* action )
{
Subscription subscription = { observer , event , action );
this->subscriptions.push_back ( subscription );
};
Action派生类的示例:
class myAction: public Action {
public:
// Implement the DoThis() method
void SomeResultType DoThis() {
cout << "Hello World!";
return SomeValue;
}
};
// To use the action,
myAction* act = new myAction;
myEventDispatcher.AddEventListener(someObserver, "HelloWorld", act);
这是实现操作(和回调)最安全的方法之一。
在最简单的形式中,u_u可以是一个函数指针,例如
typedef void (*u_u)(void*); // or whatever arguments u like
然后只需提供一个函数,该函数在事件被触发时被调用。
void myaction(void* arg)
{
...
}
Subscription s;
...
s.action = myaction;
相关文章:
- 如何设计具有不同类型的通知和观察器的观察者模式?
- 观察者模式:为什么主题应该是抽象的?
- 如何在不必绑定到特定类的情况下实现观察者模式
- C++11观察者模式(信号、插槽、事件、更改广播器/侦听器,或任何您想称之为的东西)
- C++自己的观察者模式
- 不同可观察量的观察者模式
- 通过Boost信号的观察者模式2
- 具有类型信息的观察者模式(C++)
- 观察者模式和继承:未调用正确的函数
- 多少听众是太多的观察者模式
- 当观察者希望观察不同的项目时实现观察者模式
- std::函数回调,参数采用观察者模式(寄存器主题上的占位符)
- 引用自定义容器的C++观察者模式
- 是否为每个模板实例化生成唯一的类型或id?(观察者模式示例)
- 从c代码中的c++库导出观察者模式
- 消息系统的观察者模式+访问者模式
- 实现观察者模式的问题:"Member reference base type ________ is not a structure or union"
- 在Qt信号/槽的上下文中使用观察者模式
- C++中的通用观察者模式
- 使用weak_ptr的观察者模式