记不清出处了,实现代码是别人的,自己整理的
//delegate.h
/*! @file @author Albert Semenov @date 11/2007 @module */ /* This file is part of MyGUI. MyGUI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. MyGUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with MyGUI. If not, see <http://www.gnu.org/licenses/>. */ #ifndef __DELEGATE_H__ #define __DELEGATE_H__ #include <typeinfo> #include <list> namespace delegates { // base class for classes that want to detach themselves from the multi delegates class IDelegateUnlink { public: virtual ~IDelegateUnlink() { } IDelegateUnlink() { m_baseDelegateUnlink = this; } bool compare(IDelegateUnlink * _unlink) const { return m_baseDelegateUnlink == _unlink->m_baseDelegateUnlink; } private: IDelegateUnlink * m_baseDelegateUnlink; }; inline IDelegateUnlink * GetDelegateUnlink(void * _base) { return 0; } inline IDelegateUnlink * GetDelegateUnlink(IDelegateUnlink * _base) { return _base; } } // Generation Number of delegates to the various parameters // no parameters #define DELEGATE_SUFFIX 0 #define DELEGATE_TEMPLATE #define DELEGATE_TEMPLATE_PARAMS #define DELEGATE_TEMPLATE_ARGS #define DELEGATE_T_TEMPLATE_PARAMS <typename T> #define DELEGATE_T_TEMPLATE_ARGS <T> #define DELEGATE_PARAMS #define DELEGATE_ARGS #define DELEGATE_TYPENAME #include "delegate_imp.h" // one parameter #define DELEGATE_SUFFIX 1 #define DELEGATE_TEMPLATE template #define DELEGATE_TEMPLATE_PARAMS <typename TP1> #define DELEGATE_TEMPLATE_ARGS <TP1> #define DELEGATE_T_TEMPLATE_PARAMS <typename T, typename TP1> #define DELEGATE_T_TEMPLATE_ARGS <T, TP1> #define DELEGATE_PARAMS TP1 p1 #define DELEGATE_ARGS p1 #define DELEGATE_TYPENAME typename #include "delegate_imp.h" // two parameters #define DELEGATE_SUFFIX 2 #define DELEGATE_TEMPLATE template #define DELEGATE_TEMPLATE_PARAMS <typename TP1, typename TP2> #define DELEGATE_TEMPLATE_ARGS <TP1, TP2> #define DELEGATE_T_TEMPLATE_PARAMS <typename T, typename TP1, typename TP2> #define DELEGATE_T_TEMPLATE_ARGS <T, TP1, TP2> #define DELEGATE_PARAMS TP1 p1, TP2 p2 #define DELEGATE_ARGS p1, p2 #define DELEGATE_TYPENAME typename #include "delegate_imp.h" // three parameters #define DELEGATE_SUFFIX 3 #define DELEGATE_TEMPLATE template #define DELEGATE_TEMPLATE_PARAMS <typename TP1, typename TP2, typename TP3> #define DELEGATE_TEMPLATE_ARGS <TP1, TP2, TP3> #define DELEGATE_T_TEMPLATE_PARAMS <typename T, typename TP1, typename TP2, typename TP3> #define DELEGATE_T_TEMPLATE_ARGS <T, TP1, TP2, TP3> #define DELEGATE_PARAMS TP1 p1, TP2 p2, TP3 p3 #define DELEGATE_ARGS p1, p2, p3 #define DELEGATE_TYPENAME typename #include "delegate_imp.h" // four parameters #define DELEGATE_SUFFIX 4 #define DELEGATE_TEMPLATE template #define DELEGATE_TEMPLATE_PARAMS <typename TP1, typename TP2, typename TP3, typename TP4> #define DELEGATE_TEMPLATE_ARGS <TP1, TP2, TP3, TP4> #define DELEGATE_T_TEMPLATE_PARAMS <typename T, typename TP1, typename TP2, typename TP3, typename TP4> #define DELEGATE_T_TEMPLATE_ARGS <T, TP1, TP2, TP3, TP4> #define DELEGATE_PARAMS TP1 p1, TP2 p2, TP3 p3, TP4 p4 #define DELEGATE_ARGS p1, p2, p3, p4 #define DELEGATE_TYPENAME typename #include "delegate_imp.h" // five parameters #define DELEGATE_SUFFIX 5 #define DELEGATE_TEMPLATE template #define DELEGATE_TEMPLATE_PARAMS <typename TP1, typename TP2, typename TP3, typename TP4, typename TP5> #define DELEGATE_TEMPLATE_ARGS <TP1, TP2, TP3, TP4, TP5> #define DELEGATE_T_TEMPLATE_PARAMS <typename T, typename TP1, typename TP2, typename TP3, typename TP4, typename TP5> #define DELEGATE_T_TEMPLATE_ARGS <T, TP1, TP2, TP3, TP4, TP5> #define DELEGATE_PARAMS TP1 p1, TP2 p2, TP3 p3, TP4 p4, TP5 p5 #define DELEGATE_ARGS p1, p2, p3, p4, p5 #define DELEGATE_TYPENAME typename #include "delegate_imp.h" #endif // __DELEGATE_H__
/*! @file @author Albert Semenov @date 11/2007 @module */ /* This file is part of MyGUI. MyGUI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. MyGUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with MyGUI. If not, see <http://www.gnu.org/licenses/>. */ namespace delegates { #define MYGUI_COMBINE(a, b) MYGUI_COMBINE1(a, b) #define MYGUI_COMBINE1(a, b) a##b #define MYGUI_I_DELEGATE MYGUI_COMBINE(IDelegate, DELEGATE_SUFFIX) #define MYGUI_C_STATIC_DELEGATE MYGUI_COMBINE(CStaticDelegate, DELEGATE_SUFFIX) #define MYGUI_C_METHOD_DELEGATE MYGUI_COMBINE(CMethodDelegate, DELEGATE_SUFFIX) #define MYGUI_C_DELEGATE MYGUI_COMBINE(CDelegate, DELEGATE_SUFFIX) #define MYGUI_C_MULTI_DELEGATE MYGUI_COMBINE(CMultiDelegate, DELEGATE_SUFFIX) // base class of all delegates DELEGATE_TEMPLATE DELEGATE_TEMPLATE_PARAMS class MYGUI_I_DELEGATE { public: virtual ~MYGUI_I_DELEGATE() { } virtual bool isType(const std::type_info& _type) = 0; virtual void invoke(DELEGATE_PARAMS) = 0; virtual bool compare(MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS * _delegate) const = 0; virtual bool compare(IDelegateUnlink * _unlink) const { return false; } }; // delegate to a static function DELEGATE_TEMPLATE DELEGATE_TEMPLATE_PARAMS class MYGUI_C_STATIC_DELEGATE : public MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS { public: typedef void(*Func)(DELEGATE_PARAMS); MYGUI_C_STATIC_DELEGATE(Func _func) : mFunc(_func) { } virtual bool isType(const std::type_info& _type) { return typeid(MYGUI_C_STATIC_DELEGATE DELEGATE_TEMPLATE_ARGS) == _type; } virtual void invoke(DELEGATE_PARAMS) { mFunc(DELEGATE_ARGS); } virtual bool compare(MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS * _delegate) const { if (0 == _delegate || !_delegate->isType(typeid(MYGUI_C_STATIC_DELEGATE DELEGATE_TEMPLATE_ARGS))) return false; MYGUI_C_STATIC_DELEGATE DELEGATE_TEMPLATE_ARGS * cast = static_cast<MYGUI_C_STATIC_DELEGATE DELEGATE_TEMPLATE_ARGS *>(_delegate); return cast->mFunc == mFunc; } virtual bool compare(IDelegateUnlink * _unlink) const { return false; } private: Func mFunc; }; // delegate for the method of the class template DELEGATE_T_TEMPLATE_PARAMS class MYGUI_C_METHOD_DELEGATE : public MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS { public: typedef void (T::*Method)(DELEGATE_PARAMS); MYGUI_C_METHOD_DELEGATE(IDelegateUnlink * _unlink, T * _object, Method _method) : mUnlink(_unlink), mObject(_object), mMethod(_method) { } virtual bool isType(const std::type_info& _type) { return typeid(MYGUI_C_METHOD_DELEGATE DELEGATE_T_TEMPLATE_ARGS) == _type; } virtual void invoke(DELEGATE_PARAMS) { (mObject->*mMethod)(DELEGATE_ARGS); } virtual bool compare(MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS * _delegate) const { if (0 == _delegate || !_delegate->isType(typeid(MYGUI_C_METHOD_DELEGATE DELEGATE_T_TEMPLATE_ARGS))) return false; MYGUI_C_METHOD_DELEGATE DELEGATE_T_TEMPLATE_ARGS * cast = static_cast<MYGUI_C_METHOD_DELEGATE DELEGATE_T_TEMPLATE_ARGS *>(_delegate); return cast->mObject == mObject && cast->mMethod == mMethod; } virtual bool compare(IDelegateUnlink * _unlink) const { return mUnlink == _unlink; } private: IDelegateUnlink *mUnlink; T * mObject; Method mMethod; }; } // namespace delegates // template to create a delegate static function // parameters: a pointer to a function // example : newDelegate(funk_name); // example : newDelegate(class_name::static_method_name); DELEGATE_TEMPLATE DELEGATE_TEMPLATE_PARAMS inline delegates::MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS * newDelegate(void(*_func)(DELEGATE_PARAMS)) { return new delegates::MYGUI_C_STATIC_DELEGATE DELEGATE_TEMPLATE_ARGS(_func); } // template to create a delegate class method // options : pointer to the class object and a pointer to a class method // example : newDelegate(&object_name, &class_name::method_name); template DELEGATE_T_TEMPLATE_PARAMS inline delegates::MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS * newDelegate(T * _object, void (T::*_method)(DELEGATE_PARAMS)) { return new delegates::MYGUI_C_METHOD_DELEGATE DELEGATE_T_TEMPLATE_ARGS(delegates::GetDelegateUnlink(_object), _object, _method); } namespace delegates { // pattern of the delegate class DELEGATE_TEMPLATE DELEGATE_TEMPLATE_PARAMS class MYGUI_C_DELEGATE { public: typedef MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS IDelegate; MYGUI_C_DELEGATE() : mDelegate(0) { } MYGUI_C_DELEGATE(const MYGUI_C_DELEGATE DELEGATE_TEMPLATE_ARGS& _event) { // pick up his own mDelegate = _event.mDelegate; const_cast<MYGUI_C_DELEGATE DELEGATE_TEMPLATE_ARGS&>(_event).mDelegate = 0; } ~MYGUI_C_DELEGATE() { clear(); } bool empty() const { return mDelegate == 0; } void clear() { if (mDelegate) { delete mDelegate; mDelegate = 0; } } MYGUI_C_DELEGATE DELEGATE_TEMPLATE_ARGS & operator=(IDelegate* _delegate) { delete mDelegate; mDelegate = _delegate; return *this; } MYGUI_C_DELEGATE DELEGATE_TEMPLATE_ARGS & operator=(const MYGUI_C_DELEGATE DELEGATE_TEMPLATE_ARGS& _event) { // pick up his own delete mDelegate; mDelegate = _event.mDelegate; const_cast<MYGUI_C_DELEGATE DELEGATE_TEMPLATE_ARGS&>(_event).mDelegate = 0; return *this; } void operator()(DELEGATE_PARAMS) { if (mDelegate == 0) return; mDelegate->invoke(DELEGATE_ARGS); } private: IDelegate * mDelegate; }; // template class multi delegate DELEGATE_TEMPLATE DELEGATE_TEMPLATE_PARAMS class MYGUI_C_MULTI_DELEGATE { public: typedef MYGUI_I_DELEGATE DELEGATE_TEMPLATE_ARGS IDelegate; typedef DELEGATE_TYPENAME std::list<IDelegate* /*, Allocator<IDelegate*>*/ > ListDelegate; typedef DELEGATE_TYPENAME ListDelegate::iterator ListDelegateIterator; typedef DELEGATE_TYPENAME ListDelegate::const_iterator ConstListDelegateIterator; MYGUI_C_MULTI_DELEGATE() { } ~MYGUI_C_MULTI_DELEGATE() { clear(); } bool empty() const { for (ConstListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter) { if (*iter) return false; } return true; } void clear() { for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter) { if (*iter) { delete (*iter); (*iter) = 0; } } } void clear(IDelegateUnlink * _unlink) { for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter) { if ((*iter) && (*iter)->compare(_unlink)) { delete (*iter); (*iter) = 0; } } } MYGUI_C_MULTI_DELEGATE DELEGATE_TEMPLATE_ARGS & operator+=(IDelegate* _delegate) { for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter) { if ((*iter) && (*iter)->compare(_delegate)) { delete _delegate; return *this; //MYGUI_ASSERT(false, "dublicate delegate"); } } mListDelegates.push_back(_delegate); return *this; } MYGUI_C_MULTI_DELEGATE DELEGATE_TEMPLATE_ARGS & operator-=(IDelegate* _delegate) { for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter) { if ((*iter) && (*iter)->compare(_delegate)) { // verify the identity of the delegates if ((*iter) != _delegate) delete (*iter); (*iter) = 0; break; } } delete _delegate; return *this; } void operator()(DELEGATE_PARAMS) { ListDelegateIterator iter = mListDelegates.begin(); while (iter != mListDelegates.end()) { if (0 == (*iter)) { iter = mListDelegates.erase(iter); } else { (*iter)->invoke(DELEGATE_ARGS); ++iter; } } } private: // constructor and operator =, without implementation, just for private MYGUI_C_MULTI_DELEGATE(const MYGUI_C_MULTI_DELEGATE DELEGATE_TEMPLATE_ARGS & _event); MYGUI_C_MULTI_DELEGATE DELEGATE_TEMPLATE_ARGS & operator=(const MYGUI_C_MULTI_DELEGATE DELEGATE_TEMPLATE_ARGS & _event); private: ListDelegate mListDelegates; }; #undef MYGUI_COMBINE #undef MYGUI_COMBINE1 #undef MYGUI_I_DELEGATE #undef MYGUI_C_STATIC_DELEGATE #undef MYGUI_C_METHOD_DELEGATE #undef MYGUI_C_DELEGATE #undef MYGUI_C_MULTI_DELEGATE #undef DELEGATE_SUFFIX #undef DELEGATE_TEMPLATE #undef DELEGATE_TEMPLATE_PARAMS #undef DELEGATE_TEMPLATE_ARGS #undef DELEGATE_T_TEMPLATE_PARAMS #undef DELEGATE_T_TEMPLATE_ARGS #undef DELEGATE_PARAMS #undef DELEGATE_ARGS #undef DELEGATE_TYPENAME } // namespace delegates
#ifndef _OBSERVER_H_ #define _OBSERVER_H_ #include <QVector> #include <QString> #include <vector> #include <iostream> #include "delegate.h" using namespace std; class Observer; /*主题基类*/ class Subject { public: virtual void SetSujectState( string status) { subjectState = status; } virtual string GetSujectState() { return subjectState; } virtual void Notify(){}; protected: string subjectState; }; /*具体主题类*/ class ConcreteSubject : public Subject { public: ConcreteSubject() { } private: }; /*观察者基类*/ class Observer { public: virtual void Update(){}; }; /*具体观察者*/ class ConcreteObserver : public Observer { public: ConcreteObserver(ConcreteSubject* pSubject, string name) { m_psubject = pSubject; m_name = name; } void SetSubject(ConcreteSubject* pSubject) { m_psubject = pSubject; } ConcreteSubject* GetSubject( ) { return m_psubject; } virtual void Update() { observerState = m_psubject->GetSujectState(); cout << "观察者:"<<m_name<<"知道,主题的状态为:" <<observerState<< endl; } private: string m_name; string observerState; ConcreteSubject* m_psubject; }; class StockObserver { private: string m_name; Subject* m_pSubject; //主题通知者 public: StockObserver( string name, Subject* pSubject) { this->m_name = name; this->m_pSubject = pSubject; } //关闭股票行情 void CloseStockMarket() { cout << m_name << "关闭股票行情软件" << endl; } void OpenStockMarket() { cout << m_name << "打开股票行情软件" << endl; } }; class NBAObserver { public: NBAObserver( string name, Subject* psub) { this->m_name = name; this->m_pSubject = psub; } void CloseNBADirectSending() { cout << m_name << "关闭NBA直播,继续工作" << endl; } void OpenNBADirectSending() { cout << m_name << "停止工作,打开NBA直播" << endl; } private: string m_name; Subject* m_pSubject; }; class Boss : public Subject { typedef delegates::CMultiDelegate0 EvenetHandler; typedef delegates::CMultiDelegate1< int> EventHandler1; public: EvenetHandler event; // 委托事件 EvenetHandler event2; EventHandler1 event3; void Notify() { if (subjectState == "我回来了") { event(); } else if (subjectState == "我出去了") { event2(); } } }; #endif
#include <QtCore/QCoreApplication> #include "Observer.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Boss* huhansan = new Boss(); StockObserver* tongshi1 = new StockObserver(string("aa"), huhansan); NBAObserver* tongshi2 = new NBAObserver(string("bb"),huhansan); huhansan->event += newDelegate( tongshi1, &StockObserver::CloseStockMarket ); huhansan->event += newDelegate( tongshi2, &NBAObserver::CloseNBADirectSending); huhansan->event2 += newDelegate( tongshi1, &StockObserver::OpenStockMarket); huhansan->event2 += newDelegate( tongshi2, &NBAObserver::OpenNBADirectSending); string inputstatus; while (cin >> inputstatus, inputstatus != "quit") { huhansan->SetSujectState( inputstatus ); huhansan->Notify(); //huhansan->event2.clear( tongshi1); } return a.exec(); }