青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

來吧,朋友!

為C++瘋狂

Generic Observer Pattern and Events in C++

Introduction

One of the interesting features I found in C# is a ?Events and Delegates? concept. The idea is good but not new in Object Oriented Programming, it is one of the most frequently used concepts in programming, sometimes referred to as ?Observer? or ?Document/View? design pattern. Classical formulation of it could be found in ?Design Patterns, Elements of Reusable Object Oriented Software? by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (The Gang of Four).

This concept is used when you want some information stored in one object, called ?model? (subject) to be watched by others, called ?views? (observers). Each time when information is changed in the ?model?, ?views? attached to the model should receive notification and update there states accordingly to the changed ?model?.

Classical implementation described in ?Design Patterns?:

As it is seen from the class diagram, concrete models should be derived from Subject class and views from Observer. Any time the state of Subject is changed, it calls notify method which notifies all observers attached to the Subject.

Collapse Copy Code
void Subject::notify()
{
for(int i=0; i<observes.size(); i++)
observers[i]->update();
}

In many applications, this straightforward implementation is good enough, but things are getting ugly when you have different kinds of changes in the ?subject? and you want to pass different types of parameters to the ?views?.

One of the examples for complex ?Model?/?View? relations is a GUI control attached to its processing function. Each time the control?s state is changed, process function is called with parameters indicating new state of the control.

These kinds of problems are solved in C# by the introduction of ?Events and Delegates? concept. The resolution of the problem is easier in C#, because all classes are inherited from the same ?object? class.

At the beginning, I thought why we do not have this nice ?Events and Delegates? thing in standard C++, but then I came to the conclusion that C++ does not need it.

C++ language is powerful enough to express ?Events? and ?Delegates? concept in terms of already existing primitives. Proposed design makes it possible to "connect" different methods with different number of parameters belonging to unrelated classes to the ?model?.

The keys for this solution are C++ templates (generic types) and pointes to member functions.

Using Code

Suppose we have a class MySubject that has internal information connected to different views, it produces three different types of events called int_event, double_event and triple_event with different types and numbers of parameters.

Collapse Copy Code
class MySubject
{
public:
CppEvent1<bool,int> int_event;
CppEvent2<bool,double,int> double_event;
CppEvent3<bool,double,int,const char*> triple_event;
void submit_int()
{
int_event.notify(1);
}
void submit_double()
{
double_event.notify(10.5,100);
}
void submit_triple()
{
triple_event.notify(10.5,100,"Oh ye");
}
};

Views represented by MyListener1 and MyListener2 are unrelated. The only requirement is for callback (delegate) methods to have parameters signature similar to corresponding CppEvent.

Collapse Copy Code
class MyListener1
{
public:
bool update_int(int p)
{
Console::WriteLine(S"int update listener 1");
return true;
}
bool update_double(double p,int p1)
{
Console::WriteLine(S"double update listener 1");
return true;
}
bool update_triple(double p,int p1,const char* str)
{
Console::WriteLine(S"triple update listener 1");
return true;
}
};
class MyListener2
{
public:
bool fun(int p)
{
Console::WriteLine(S"int update listener 2");
return true;
}
};

The final step is to create viewers MyListener1 and MyListener2 and connect their member functions to corresponding events in MySubject model.

Collapse Copy Code
int main(void)
{
// create listeners (viewers)
    MyListener1* listener1 = new MyListener1;
MyListener2* listener2 = new MyListener2;
// create model
    MySubject subject;
// connect different viewers to different events of the model
    CppEventHandler h1 = subject.int_event.attach(listener1,
&MyListener1::update_int);
CppEventHandler h2 = subject.int_event.attach(listener2,
&MyListener2::fun);
CppEventHandler h3 = subject.double_event.attach(listener1,
&MyListener1::update_double);
CppEventHandler h4 = subject.triple_event.attach(listener1,
&MyListener1::update_triple);
// generate events
    subject.submit_int();
subject.submit_double();
subject.submit_triple();
// detach handlers
    subject.int_event.detach(h1);
subject.int_event.detach(h2);
subject.double_event.detach(h3);
subject.triple_event.detach(h4);
return 0;
}

Resulting output is:

Collapse Copy Code
> int update listener 1
> int update listener 2
> double update listener 1
> triple update listener 1

Implementation

First of all, if we want to attach different types of event handles (member functions with same types of parameters from different classes) to the same event, we should provide common base for them. We use templates to make it generic for any combination of parameter types in ?delegate? or call back method. There are different event types for every number of arguments in callback function.

Collapse Copy Code
// Event handler base for delegate with 1 parameter
template <typename ReturnT,typename ParamT>
class EventHandlerBase1
{
public:
virtual ReturnT notify(ParamT param) = 0;
};

Specific type of member function pointer within a pointer to the object is stored in the derived class.

Collapse Copy Code
template <typename ListenerT,typename ReturnT,typename ParamT>
class EventHandler1 : public EventHandlerBase1<ReturnT,ParamT>
{
typedef ReturnT (ListenerT::*PtrMember)(ParamT);
ListenerT* m_object;
PtrMember m_member;
public:
EventHandler1(ListenerT* object, PtrMember member)
: m_object(object), m_member(member)
{}
ReturnT notify(ParamT param)
{
return (m_object->*m_member)(param);
}
};

Event class stores map of event handlers and notifies all of them when notify method is called. Detach method is used to release handler from the map.

Collapse Copy Code
template <typename ReturnT,typename ParamT>
class CppEvent1
{
typedef std::map<int,EventHandlerBase1<ReturnT,ParamT> *> HandlersMap;
HandlersMap m_handlers;
int m_count;
public:
CppEvent1()
: m_count(0) {}
template <typename ListenerT>
CppEventHandler attach(ListenerT* object,ReturnT (ListenerT::*member)(ParamT))
{
typedef ReturnT (ListenerT::*PtrMember)(ParamT);
m_handlers[m_count] = (new EventHandler1<ListenerT,
ReturnT,ParamT>(object,member));
m_count++;
return m_count-1;
}
bool detach(CppEventHandler id)
{
HandlersMap::iterator it = m_handlers.find(id);
if(it == m_handlers.end())
return false;
delete it->second;
m_handlers.erase(it);
return true;
}
ReturnT notify(ParamT param)
{
HandlersMap::iterator it = m_handlers.begin();
for(; it != m_handlers.end(); it++)
{
it->second->notify(param);
}
return true;
}
};

Comments

This implementation is quite similar to those in the article ?Emulating C# delegates in Standard C++?. I found out it after I already wrote the article. Actually, the fact that we have a similar way to deal with the problem means that it?s a very intuitive solution for this kind of problem in C++. An advantage of the current implementation is that it supports different number of arguments, so any member function of any class could be a callback (delegate). Probably to have this thing as a part of standard library is a good thing, but even if it?s not a part of the standard, you can use it as it is. This implementation is restricted to events up to 3 parameters, it can be easily extended to other numbers by just rewriting it with different number of parameters (see code for details).

License

posted on 2009-07-22 14:51 yanghaibao 閱讀(499) 評論(0)  編輯 收藏 引用

導(dǎo)航

<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

統(tǒng)計

常用鏈接

留言簿

隨筆分類

隨筆檔案

文章檔案

收藏夾

Good blogs

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产日韩在线播放| 欧美日韩国产高清视频| 国产精品视频内| 羞羞漫画18久久大片| 亚洲一区中文| 在线播放豆国产99亚洲| 欧美粗暴jizz性欧美20| 欧美阿v一级看视频| 亚洲经典三级| 一本色道久久综合亚洲精品不卡| 欧美三级午夜理伦三级中文幕 | 欧美日韩中国免费专区在线看| 亚洲老司机av| 亚洲一区二区欧美日韩| 国模私拍视频一区| 亚洲国产精品久久久久久女王| 欧美99在线视频观看| 亚洲一区二区三区免费在线观看 | 中日韩在线视频| 国产精品女主播在线观看 | 亚洲精品专区| 99视频精品免费观看| 亚洲影院在线观看| 亚洲在线免费观看| 亚洲激情另类| 中文国产成人精品久久一| 国产欧美亚洲一区| 欧美大片va欧美在线播放| 欧美调教vk| 欧美成人精品福利| 国产精品一区免费观看| 欧美激情国产高清| 国产视频亚洲| 亚洲毛片av在线| 伊伊综合在线| 亚洲影院色无极综合| 亚洲精品一区二区三区四区高清| 99亚洲一区二区| 亚洲高清色综合| 亚洲综合第一页| 一本久久综合亚洲鲁鲁| 久久久久国产精品一区| 亚洲在线视频网站| 欧美一区二区三区视频在线| 国产精品99久久久久久久久| 久久综合九色九九| 欧美一区二区视频97| 欧美伦理一区二区| 久久亚洲影院| 国产欧美日韩免费| 亚洲私拍自拍| 亚洲调教视频在线观看| 欧美高清日韩| 久久天堂国产精品| 国产日韩高清一区二区三区在线| 一本色道久久综合狠狠躁的推荐| 99riav久久精品riav| 欧美+日本+国产+在线a∨观看| 性欧美大战久久久久久久久| 欧美久久视频| 亚洲国产成人精品视频| 亚洲国产欧美久久| 鲁大师影院一区二区三区| 老司机午夜精品视频在线观看| 国产综合欧美| 欧美在线观看一区二区三区| 久久精品国产亚洲5555| 国产亚洲精品福利| 欧美一区二区三区视频在线观看| 欧美在线高清| 狠狠色香婷婷久久亚洲精品| 久久激情网站| 欧美大片一区二区| 亚洲欧洲美洲综合色网| 欧美理论在线播放| 亚洲精品一区久久久久久| 亚洲视频狠狠| 国产精品国产三级国产专区53| 尤物在线观看一区| 欧美成人精品三级在线观看| 亚洲国产导航| 亚洲影视九九影院在线观看| 国产精品亚洲不卡a| 欧美在线3区| 欧美不卡一区| 亚洲视频在线观看| 国产麻豆综合| 毛片一区二区三区| 日韩视频第一页| 欧美一区二区性| 亚洲成色777777女色窝| 欧美成人dvd在线视频| 99精品热视频只有精品10| 亚洲女ⅴideoshd黑人| 国产亚洲精品久久久久婷婷瑜伽| 免费在线欧美黄色| 中文欧美字幕免费| 久久中文字幕一区| 亚洲一区二区三区在线观看视频 | 牛牛影视久久网| 亚洲视频精选| 欧美成人精品1314www| 亚洲先锋成人| 国语自产在线不卡| 欧美激情91| 久久国产精品毛片| 99视频精品全部免费在线| 久久婷婷人人澡人人喊人人爽| 日韩视频在线观看国产| 国内偷自视频区视频综合| 欧美精品国产精品| 久久精品欧美| 亚洲一区二区三区激情| 亚洲国内在线| 久久人人97超碰人人澡爱香蕉| 亚洲视频1区2区| 亚洲国产精品久久久久秋霞影院| 国产精品久久久久99| 欧美韩日一区二区三区| 久久久.com| 亚洲欧美在线免费| 一区二区三区精品| 亚洲承认在线| 欧美aaaaaaaa牛牛影院| 久久精品亚洲一区二区| 亚洲免费伊人电影在线观看av| 日韩视频三区| 亚洲日产国产精品| 雨宫琴音一区二区在线| 国产一区二区中文| 国产精品国产三级国产专播精品人 | 一本久久a久久精品亚洲| 一区二区在线观看av| 国产日韩欧美在线播放| 国产精品国产三级国产aⅴ浪潮| 欧美精品亚洲精品| 欧美h视频在线| 麻豆精品网站| 久久综合久久综合九色| 久久米奇亚洲| 老司机aⅴ在线精品导航| 久久久亚洲综合| 午夜视黄欧洲亚洲| 新片速递亚洲合集欧美合集| 亚洲欧美一区二区在线观看| 亚洲综合第一| 香蕉久久精品日日躁夜夜躁| 欧美亚洲一区在线| 久久se精品一区二区| 久久九九国产| 久久综合久久综合这里只有精品 | 欧美成人午夜| 欧美激情在线狂野欧美精品| 亚洲国产精品久久久久婷婷884| 欧美国产日韩在线| 亚洲精品护士| 中日韩美女免费视频网址在线观看| 亚洲精品国产精品久久清纯直播 | 久久久久久久999| 久久先锋影音| 欧美高清视频www夜色资源网| 欧美激情亚洲另类| 欧美特黄一级大片| 国模精品一区二区三区色天香| 亚洲国产aⅴ天堂久久| a91a精品视频在线观看| 亚洲免费在线精品一区| 欧美影院成人| 亚洲国产精品99久久久久久久久| 91久久在线视频| 亚洲欧美第一页| 久久久久一区二区三区| 欧美巨乳在线| 国产农村妇女精品一区二区| 在线看日韩av| 亚洲伊人观看| 久久综合五月天婷婷伊人| 亚洲国产欧美在线人成| 正在播放日韩| 久久人人精品| 国产精品家庭影院| 在线精品福利| 午夜日韩在线观看| 欧美国产丝袜视频| 亚洲一区二区三区四区中文| 久久久精品动漫| 欧美午夜欧美| 亚洲电影在线播放| 亚洲欧美日韩人成在线播放| 亚洲破处大片| 亚洲在线不卡| 亚洲国产视频a| 亚洲欧美一区二区原创| 欧美freesex8一10精品| 国内精品视频666| 亚洲欧美日韩区| 日韩午夜免费| 欧美成人小视频| 国内久久婷婷综合| 欧美亚洲视频在线看网址|