C++实现的委托机制(三)

来源:互联网 发布:mac用迅雷下不了东西? 编辑:程序博客网 时间:2024/05/16 09:33

C++实现的委托机制(三)

作者:gouki04(啊古)  撰写日期:2011-10-08

博客链接:http://blog.csdn.net/gouki04

1.引言

    按上一篇文章的方法,你已经可以使用任意参数的函数委托了。这里介绍下MyGUI实现的两个辅助类,CDelegate类和IDelegateUnlink。如果你不为了深入了解MyGUI的委托实现,可以跳过此处。CDelegate即为单委托,实际效果跟函数指针差不多,于CMultiDelegate的区别在于其不支持多播。而IDelegateUnlink类主要是在CMultiDelegate中使用,在多播下一次性去掉自身的所有委托。

    注:最终的实现代码可以在这里下载:http://download.csdn.net/detail/gouki04/3641328

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()    {        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;};

    所谓断开委托,只能用在多重委托,即CMultiDelegate中,可以断开自身与其相连的所有委托。使用方法就在将自身的类从IDelegateUnlink派生,然后使用CMultiDelegate中的clear函数即可断开委托,在下面会有例子说明。

4.测试

/* 测试Delegate对不同函数的支持,可以参考下不同函数的使用方式 */#include "delegate.h"#include <iostream>using namespace std;// 普通函数1void func(int a, int b){    cout << "func(" << a << ", " << b << ")" << endl;}// 普通函数2void 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;}