程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++實現的委托機制(3)

C++實現的委托機制(3)

編輯:C++入門知識

1.引言

按上一篇文章的方法,你已經可以使用任意參數的函數委托了。這裡介紹下MyGUI實現的兩個輔助類,CDelegate類和IDelegateUnlink。如果你不為了深入了解MyGUI的委托實現,可以跳過此處。CDelegate即為單委托,實際效果跟函數指針差不多,於CMultiDelegate的區別在於其不支持多播。而IDelegateUnlink類主要是在CMultiDelegate中使用,在多播下一次性去掉自身的所有委托。


2.單委托
// 無參的單委托實現  
class CDelegate 

public: 
    typedef CDelegate IDelegate; 
 
 
    CDelegate () : mDelegate(0) { } 
    CDelegate (const CDelegate& _event) 
    { 
        // 在拷貝構造時,將被拷貝的委托去掉,即委托只存在一份  
        mDelegate = _event.mDelegate; 
        const_cast<CDelegate&>(_event).mDelegate = 0; 
    } 
    ~CDelegate () { clear(); } 
 
 
    bool empty() const { return mDelegate == 0; } 
 
 
    void clear() 
    {   www.2cto.com
        if (mDelegate) 
        { 
            delete mDelegate; 
            mDelegate = 0; 
        } 
    } 
 
 
    CDelegate & operator=(IDelegate* _delegate) 
    { 
        delete mDelegate; 
        mDelegate = _delegate; 
        return *this; 
    } 
 
 
    CDelegate & operator=(const CDelegate& _event) 
    { 
        // 在賦值時,將右值的委托去掉,即委托只存在一份  
        delete mDelegate; 
        mDelegate = _event.mDelegate; 
        const_cast<CDelegate&>(_event).mDelegate = 0; 
 
 
        return *this; 
    } 
 
 
    void operator()( ) 
    { 
        if (mDelegate == 0) return; 
        mDelegate->invoke( ); 
    } 
 
 
private: 
    IDelegate * mDelegate; 
}; 
// 無參的單委托實現
class CDelegate
{
public:
    typedef CDelegate IDelegate;


    CDelegate () : mDelegate(0) { }
    CDelegate (const CDelegate& _event)
    {
        // 在拷貝構造時,將被拷貝的委托去掉,即委托只存在一份
        mDelegate = _event.mDelegate;
        const_cast<CDelegate&>(_event).mDelegate = 0;
    }
    ~CDelegate () { clear(); }


    bool empty() const { return mDelegate == 0; }


    void clear()
    {
        if (mDelegate)
        {
            delete mDelegate;
            mDelegate = 0;
        }
    }


    CDelegate & operator=(IDelegate* _delegate)
    {
        delete mDelegate;
        mDelegate = _delegate;
        return *this;
    }


    CDelegate & operator=(const CDelegate& _event)
    {
        // 在賦值時,將右值的委托去掉,即委托只存在一份
        delete mDelegate;
        mDelegate = _event.mDelegate;
        const_cast<CDelegate&>(_event).mDelegate = 0;


        return *this;
    }


    void operator()( )
    {
        if (mDelegate == 0) return;
        mDelegate->invoke( );
    }


private:
    IDelegate * mDelegate;
};可以看到,單委托只實現了 = 運算符,沒有實現 += 運算符。
而且在賦值時會將原委托去掉,確保只有一份委托。
其實單委托跟普通函數指針差不多,在使用單委托的地方可以換成使用普通函數指針。


3.斷開委托
// 斷開委托的基類  
class IDelegateUnlink 

public: 
    virtual ~IDelegateUnlink() { } 
 
 
    IDelegateUnlink() { m_baseDelegateUnlink = this; } 
    bool compare(IDelegateUnlink * _unlink) const { return m_baseDelegateUnlink == _unlink->m_baseDelegateUnlink; } 
 
 
private: 
    IDelegateUnlink * m_baseDelegateUnlink; 
}; 
// 斷開委托的基類
class IDelegateUnlink
{
public:
    virtual ~IDelegateUnlink() { }


    IDelegateUnlink() { m_baseDelegateUnlink = this; }
    bool compare(IDelegateUnlink * _unlink) const { return m_baseDelegateUnlink == _unlink->m_baseDelegateUnlink; }


private:
    IDelegateUnlink * m_baseDelegateUnlink;
};所謂斷開委托,只能用在多重委托,即CMultiDelegate中,可以斷開自身與其相連的所有委托。
使用方法就在將自身的類從IDelegateUnlink派生,然後使用CMultiDelegate中的clear函數即可斷開委托。
在下面會有例子說明。


4.測試

/* 測試Delegate對不同函數的支持
 * 可以參考下不同函數的使用方式
 */ 
#include "delegate.h"  
#include <iostream>  
 
 
using namespace std; 
 
 
// 普通函數1  
void func(int a, int b) 

    cout << "func(" << a << ", " << b << ")" << endl; 

 
 
// 普通函數2  
void func2(int a, int b) 

    cout << "func2(" << a << ", " << b << ")" << endl; 

 
 
// 普通類  
class NormalClass 

public: 
    // 類的普通成員函數  
    void normalFunc(int a, int b) 
    { 
        cout << "NormalClass::normalFunc(" << a << ", " << b << ")" << endl; 
    } 
}; 
 
 
// 實現了IDelegateUnlink的類  
class BaseUnlinkClass : public delegates::IDelegateUnlink 

public: 
    // 類的虛函數  
    virtual void virFunc(int a, int b) 
    { 
        cout << "BaseUnlinkClass::virFunc(" << a << ", " << b << ")" << endl; 
    } 
 
 
    // 類的普通成員函數  
    void normalFunc(int a, int b) 
    { 
        cout << "BaseUnlinkClass::normalFunc(" << a << ", " << b << ")" << endl; 
    } 
}; 
 
 
class DerivedClass : public BaseUnlinkClass 

public: 
    // 類的虛函數  
    virtual void virFunc(int a, int b) 
    { 
        cout << "DerivedClass::virFunc(" << a << ", " << b << ")" << endl; 
    } 
 
 
    // 類的靜態成員函數  
    static void staticFunc(int a, int b) 
    { 
        cout << "DerivedClass::staticFunc(" << a << ", " << b << ")" << endl; 
    } 
}; 
 
 
// 模板函數  
template<class T> 
void TFunc(T a, T b) 

    cout << "TFunc(" << a << ", " << b << ")" << endl; 

 
 
int main() 

    BaseUnlinkClass *baseUnlinkClass = new BaseUnlinkClass; 
    DerivedClass *derivedClass = new DerivedClass; 
    NormalClass *normalClass = new NormalClass; 
     
    // 定義委托  
    typedef delegates::CMultiDelegate2<int, int> EvenetHandler; 
    EvenetHandler event; 
 
 
    // 添加普通函數  
    event += newDelegate(func); 
    event += newDelegate(func2); 
 
 
    // 添加類的普通成員函數  
    event += newDelegate(normalClass, &NormalClass::normalFunc); 
    event += newDelegate(baseUnlinkClass, &BaseUnlinkClass::normalFunc); 
 
 
    // 添加類的虛函數  
    event += newDelegate(baseUnlinkClass, &BaseUnlinkClass::virFunc); 
    event += newDelegate(derivedClass, &DerivedClass::virFunc); 
    // 注意在多態下,使用基類指針時,函數指針要用基類的函數指針,不能用派生類的  
    // 但是在調用時會響應多態,也就是會調用派生類的虛函數  
    event += newDelegate((BaseUnlinkClass*)derivedClass, &BaseUnlinkClass::virFunc); 
 
 
    // 添加類的靜態成員函數  
    event += newDelegate(&DerivedClass::staticFunc); 
 
 
    // 添加模板函數  
    event += newDelegate(TFunc<int>); 
     
    // 觸發事件  
    event(1, 2); 
    cout << endl; 
 
 
    // 去掉函數  
    event -= newDelegate(func); 
 
 
    // 去掉baseUnlinkClass所有的函數  
    event.clear(baseUnlinkClass); 
 
 
    // 去掉derivedClass所有的函數  
    // 注意靜態成員函數staticFunc不會去掉  
    event.clear(derivedClass); 
 
 
    //event.clear(normalClass);  
    // 錯誤調用,normalClass不是IDelegateUnlink的派生類  
    // 不能使用clear去掉自身的函數  
    // 應該使用如下方法  
    event -= newDelegate(normalClass, &NormalClass::normalFunc); 
     
    // 觸發事件  
    event(2, 3); 
    cout << endl; 
 
 
    return 0; 

/* 測試Delegate對不同函數的支持
 * 可以參考下不同函數的使用方式
 */
#include "delegate.h"
#include <iostream>


using namespace std;


// 普通函數1
void func(int a, int b)
{
    cout << "func(" << a << ", " << b << ")" << endl;
}


// 普通函數2
void func2(int a, int b)
{
    cout << "func2(" << a << ", " << b << ")" << endl;
}


// 普通類
class NormalClass
{
public:
    // 類的普通成員函數
    void normalFunc(int a, int b)
    {
        cout << "NormalClass::normalFunc(" << a << ", " << b << ")" << endl;
    }
};


// 實現了IDelegateUnlink的類
class BaseUnlinkClass : public delegates::IDelegateUnlink
{
public:
    // 類的虛函數
    virtual void virFunc(int a, int b)
    {
        cout << "BaseUnlinkClass::virFunc(" << a << ", " << b << ")" << endl;
    }


    // 類的普通成員函數
    void normalFunc(int a, int b)
    {
        cout << "BaseUnlinkClass::normalFunc(" << a << ", " << b << ")" << endl;
    }
};


class DerivedClass : public BaseUnlinkClass
{
public:
    // 類的虛函數
    virtual void virFunc(int a, int b)
    {
        cout << "DerivedClass::virFunc(" << a << ", " << b << ")" << endl;
    }


    // 類的靜態成員函數
    static void staticFunc(int a, int b)
    {
        cout << "DerivedClass::staticFunc(" << a << ", " << b << ")" << endl;
    }
};


// 模板函數
template<class T>
void TFunc(T a, T b)
{
    cout << "TFunc(" << a << ", " << b << ")" << endl;
}


int main()
{
    BaseUnlinkClass *baseUnlinkClass = new BaseUnlinkClass;
    DerivedClass *derivedClass = new DerivedClass;
    NormalClass *normalClass = new NormalClass;
   
    // 定義委托
    typedef delegates::CMultiDelegate2<int, int> EvenetHandler;
    EvenetHandler event;


    // 添加普通函數
    event += newDelegate(func);
    event += newDelegate(func2);


    // 添加類的普通成員函數
    event += newDelegate(normalClass, &NormalClass::normalFunc);
    event += newDelegate(baseUnlinkClass, &BaseUnlinkClass::normalFunc);


    // 添加類的虛函數
    event += newDelegate(baseUnlinkClass, &BaseUnlinkClass::virFunc);
    event += newDelegate(derivedClass, &DerivedClass::virFunc);
    // 注意在多態下,使用基類指針時,函數指針要用基類的函數指針,不能用派生類的
    // 但是在調用時會響應多態,也就是會調用派生類的虛函數
    event += newDelegate((BaseUnlinkClass*)derivedClass, &BaseUnlinkClass::virFunc);


    // 添加類的靜態成員函數
    event += newDelegate(&DerivedClass::staticFunc);


    // 添加模板函數
    event += newDelegate(TFunc<int>);
   
    // 觸發事件
    event(1, 2);
    cout << endl;


    // 去掉函數
    event -= newDelegate(func);


    // 去掉baseUnlinkClass所有的函數
    event.clear(baseUnlinkClass);


    // 去掉derivedClass所有的函數
    // 注意靜態成員函數staticFunc不會去掉
    event.clear(derivedClass);


    //event.clear(normalClass);
    // 錯誤調用,normalClass不是IDelegateUnlink的派生類
    // 不能使用clear去掉自身的函數
    // 應該使用如下方法
    event -= newDelegate(normalClass, &NormalClass::normalFunc);
   
    // 觸發事件
    event(2, 3);
    cout << endl;


    return 0;
}

 

摘自:gouki04的專欄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved