C++委托类实现

预备知识

C++函数指针

c++中普通函数和类成员函数的声明和使用方式都不一样。
声明:类成员函数在声明的时候需要指定是哪一个类,
调用:类普通成员函数调用的时候需要明确是该类的具体实例,类静态成员函数需要指定该类。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void normalFunc() { // 普通函数
    cout << "this is a normal function!" << endl;
}
class A {
public:
    static void staticFunc() { // 静态成员函数
       cout << "this is a static function!" << endl; 
    }
    void memFunc() { // 普通成员函数
        cout << "this is a member function!" << endl; 
    }
};
int main()
{
	// 普通函数和类成员函数的指针声明
    typedef void(*funcp)();
    typedef void(A::*memfuncp)();
    funcp f1 = normalFunc;
    memfuncp f2 = &A::memFunc;
    funcp f3 = A::staticFunc;
    f1();
    // 普通函数和类成员函数的调用方式
    A a; // 声明类的具体实例
    (a.*f2)(); 
    f3();
    return 0;
}

C++的动态类型判断

typeid

无参委托函数

没有参数的委托函数的构造

1. 函数指针类实现

由于普通函数和成员函数的调用方式等存在差异,所以需要实现两种类继承一个抽象委托类。

  • 抽象类:
    实现动态类型判断的函数
    实现函数调用invoke
  • 普通函数:设计普通成员函数指针成员变量,重写相关方法。
  • 成员函数:用模板实现,设计模板类实例和模板成员函数指针变量,重写相关方法。

2. 统一委托函数生成接口实现

重载newDelegate函数,根据参数类型创建不同的委托函数。

3. 委托类实现

有一个存储函数委托指针类的列表
重载了 += 表示向这个委托注册一个函数指针,这个方法会自动判重,如果重复了就不会向里面添加。
重载了 -= 表示向这个委托注销一个函数指针,如果这个函数指针不存在就什么也不执行。
重载了 () 表示当作函数调用启动这个委托,内部就是将所有函数指针指向的函数都运行一遍。

无参无返回值函数指针类实现代码

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
// 抽象委托类
class IDelegate
{
public:
    virtual ~IDelegate(){};
    // 进行函数调用
    virtual void invoke() = 0;
    // 使用RTTI进行类型判断
    virtual bool isType(const type_info &_type) = 0;
    virtual bool compare(IDelegate *_delegate) const = 0; // 一般加下划线表示成员变量
};
// 能注册普通函数的委托类
class normalFunc : public IDelegate
{
public:
    // 定义无参函数指针
    typedef void (*normalFuncp)();
    normalFunc(normalFuncp func) : f(func) {}
    virtual void invoke()
    {
        f();
    }
    virtual bool isType(const std::type_info &_type) { return typeid(normalFunc) == _type; }
    virtual bool compare(IDelegate *_delegate) const
    {
        // 判断动态类型是否一致
        if (_delegate == 0 || !_delegate->isType(typeid(normalFunc)))
            return false;
        normalFunc *cast = dynamic_cast<normalFunc *>(_delegate);
        return cast->f == f;
    }

private:
    normalFuncp f;
};
// 能注册成员函数的委托类
template <typename T>
class memFunc : public IDelegate
{
public:
    typedef void (T::*memFuncp)();
    memFunc(T *_object, memFuncp func) : object(_object), f(func) {}
    virtual void invoke()
    {
        (object->*f)();
    }
    virtual bool isType(const std::type_info &_type) { return typeid(memFunc<T>) == _type; }
    virtual bool compare(IDelegate *_delegate) const
    {
        // 判断动态类型是否一致
        if (_delegate == 0 || !_delegate->isType(typeid(memFunc<T>)))
            return false;
        memFunc<T> *cast = dynamic_cast<memFunc<T> *>(_delegate);
        return cast->object == object && cast->f == f;
    }

private:
    T *object;
    memFuncp f;
};

// 统一的接口生成函数指针对象
IDelegate *newDelegate(void (*f)())
{
    return new normalFunc(f);
}
template <typename T>
IDelegate *newDelegate(T *object, void(T::*f)())
{
    return new memFunc<T>(object, f);
}
// example
class A
{
public:
    void func()
    {
        cout << "member func of A." << endl;
    }
};
void func()
    {
        cout << "normal func." << endl;
    }
int main()
{
    IDelegate *nf = newDelegate(func);
    A *a;
    IDelegate *mf = newDelegate<A>(a,&A::func);
    nf->invoke();
    mf->invoke();
    return 0;
}

在这里插入图片描述

委托类实现代码

// 委托类
class CMultiDelegate  
{  
public:  
    typedef std::list<IDelegate*> ListDelegate;  
    typedef ListDelegate::iterator ListDelegateIterator;  
    typedef ListDelegate::const_iterator ConstListDelegateIterator;  
  
    CMultiDelegate () { }  
    ~CMultiDelegate () { 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;  
            }  
        }  
    }  
  
    CMultiDelegate& operator+=(IDelegate* _delegate)  
    {  
        for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)  
        {  
            if ((*iter) && (*iter)->compare(_delegate))  
            {  
                delete _delegate;  
                return *this;  
            }  
        }  
        mListDelegates.push_back(_delegate);  
        return *this;  
    }  
  
    CMultiDelegate& operator-=(IDelegate* _delegate)  
    {  
        for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)  
        {  
            if ((*iter) && (*iter)->compare(_delegate))  
            {  
                if ((*iter) != _delegate) delete (*iter);  
                (*iter) = 0;  
                break;  
            }  
        }  
        delete _delegate;  
        return *this;  
    }  
  
    void operator()( )  
    {  
        ListDelegateIterator iter = mListDelegates.begin();  
        while (iter != mListDelegates.end())  
        {  
            if (0 == (*iter))  
            {  
                iter = mListDelegates.erase(iter);  
            }  
            else  
            {  
                (*iter)->invoke();  
                ++iter;  
            }  
        }  
    }  
  
private:  
    CMultiDelegate (const CMultiDelegate& _event);  
    CMultiDelegate& operator=(const CMultiDelegate& _event);  
  
private:  
    ListDelegate mListDelegates;  
};  
// example
class A
{
public:
    void func()
    {
        cout << "member func of A." << endl;
    }
};
void func()
{
    cout << "normal func." << endl;
}
int main()
{
    IDelegate *nf = newDelegate(func);
    A *a;
    IDelegate *mf = newDelegate<A>(a, &A::func);
    CMultiDelegate s;
    s+=nf;
    s+=mf;
    s();
    s-=nf;
    cout << "-----" << endl;
    s();
    return 0;
}

在这里插入图片描述
参考
可变参委托类实现

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值