关于c++委托机制的实现(三)

5 篇文章 0 订阅
4 篇文章 0 订阅

写自己的bug,让自己无bug可写

上一篇博客地址:https://blog.csdn.net/qq_34236354/article/details/89878858,有兴趣的可以去看看

函数简介:c++中有普通函数,类静态成员函数,类普通成员函数,lamda函数

普通函数:一般指全局函数

类静态成员函数:类的静态函数,可以通过Class::Fun()形式调用

类普通成员函数:类的普通成员函数,一般是obj.fun()或pObj->fun()形式调用

lamda函数:有兴趣的可以自己百度,这里不考虑;(因为lamda函数实质是匿名函数,就是一个没有函数名的函数,从它的用途上来说本来就是提供编码便利,并且其他地方并不会出现,如果有两个或两个以上地方需要调用,那最好还是换成普通函数)

一:本次实现的是任意返回类型任意数量任意类型形参的函数的委托

二:实现

    其实实现很简单,就是把上一次讲的template <typename TParam>中的TParam换成可变形参...TParams(注意有三个点),即template <typename ... TParams>,虽然还有改一些其他地方,但核心的部分是这些;

    注意:最好自己手动敲敲,代码比较简单,所以就懒得加注释了

    抽象类要改的代码很少,也很简单,更改之后如下:

template <typename TReturn, typename ... TParams>
class IFun
{
public:
    virtual ~IFun() {}
    
    virtual TReturn operator()(TParams...) = 0;
};

    关于普通函数和类的静态成员函数抽象的类,代码如下:

template <typename TReturn, typename ... TParams>
class CStaticFun : public IFun<TReturn, TParams ... >
{
    typedef TReturn(*PFun)(TParams ...);
public:
    explicit CStaticFun(PFun pFun) : m_pFun(pFun) {}
    
    virtual TReturn operator()(TParams ... params) override
    {
        return m_pFun(params ...);
    }
private:
    PFun m_pFun;
};

    关于类的成员函数,代码如下:

template <typename TObj, typename TReturn, typename ... TParams>
class CMemberFun : public IFun<TReturn, TParams ...>
{
    typedef TReturn(TObj::*PFun)(TParams ...);
public:
    explicit CMemberFun(TObj *pObj, PFun pFun) : m_pObj(pObj), m_pFun(pFun) {}
    
    virtual TReturn operator()(TParams ... params) override
    {
        return (m_pObj->*m_pFun)(params ...);
    }
private:
    TObj *m_pObj;
    PFun  m_pFun;
};

    封装接口,对客户端提供统一的接口,代码如下:

template <typename TReturn, typename ... TParams>
class CFun : public IFun<TReturn, TParams ...>
{
public:
    explicit CFun(TReturn(*pFun)(TParams ...)) : m_pFun(new CStaticFun<TReturn, TParams ...>(pFun)) {}
    ~CFun() { delete m_pFun; }
    
    template <typename TObj>
    explicit CFun(TObj *pObj, TReturn(TObj::*pFun)(TParams ...)) : m_pFun(new CMemberFun<TObj, TReturn, TParams ...>(pObj, pFun)) {}
    
    virtual TReturn operator()(TParams ... params) override
    {
        assert(m_pFun);
        return (*m_pFun)(params ...);
    }
private:
    IFun<TReturn, TParams ...> *m_pFun;
};

这样任意返回类型任意数量任意类型形参的函数的委托就算是完成了;

下面是实例:

#include <iostream>
#include <cassert>
#include <string>

/*
 * 把上面三个类的代码复制粘贴到这里
 */

bool fun(int i) { std::cout << "这是一个函数 i = " << i << std::endl; return false; }
int fun4(int a, int b) { std::cout << "这是一个函数 a = " << a << " b = " << b << std::endl; return 0; }
class A
{
public:
    explicit A() {}
    
    static void fun1() { std::cout << "这是类的静态函数" << std::endl; }
    
    void fun2(char c) { std::cout << "这是类的成员函数 c = " << c << std::endl; }
    void fun3(int a, double b, char c, std::string str)
    {
        std::cout << "这是类的成员函数 a = " << a << " b = " << b << " c = " << c << " str =  " << str << std::endl;
    }
};

int main()
{
    A a;
    CFun<bool, int>                            f(fun);
    CFun<void>                                 f1(&A::fun1);
    CFun<void, char>                           f2(&a, &A::fun2);
    CFun<void, int, double, char, std::string> f3(&a, &A::fun3);
    CFun<int, int, int>                        f4(fun4);

    CFun<int, int, float, char> lamda([](int a, float b, char c) -> int {
        std::cout << "lamda a = " << a << " b = " << b << " c = " << c << std::endl;
        return 0;
    });
    
    f(233333);
    f1();
    f2('A');
    f3(1, 3.1415, 'A', "this is string");
    f4(1, 2);
    lamda(1, 2.3333, 'A');
    return 0;
}

运行结果:

这是一个函数 i = 233333

这是类的静态函数

这是类的成员函数 c = A

这是类的成员函数 a = 1 b = 3.1415 c = A str = this is string

这是一个函数 a = 1 b = 2

lamda a = 1 b = 2.3333 c = A  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值