写自己的bug,让自己无bug可写
上一篇博客地址:https://blog.csdn.net/qq_34236354/article/details/89876304,有兴趣的可以去看看
下一篇博客地址:https://blog.csdn.net/qq_34236354/article/details/89881722,有兴趣的可以去看看
函数简介:c++中有普通函数,类静态成员函数,类普通成员函数,lamda函数
普通函数:一般指全局函数
类静态成员函数:类的静态函数,可以通过Class::Fun()形式调用
类普通成员函数:类的普通成员函数,一般是obj.fun()或pObj->fun()形式调用
lamda函数:有兴趣的可以自己百度,这里不考虑;(因为lamda函数实质是匿名函数,就是一个没有函数名的函数,从它的用途上来说本来就是提供编码便利,并且其他地方并不会出现,如果有两个或两个以上地方需要调用,那最好还是换成普通函数)
一:本次实现的是任意返回类型,任意类型形参函数的委托 (这里的函数必须有且只有一个形参,下一次讲任意数量形参的情况)
二:实现
因为根本不知道客户端在使用时会用什么类型的返回值,有什么类型的形参,所以这里就需要使用到模板,在之前的抽象类基础上,稍加修改即可,代码如下
template <typename TReturn, typename TParam>
class IFun
{
public:
virtual ~IFun() {}
virtual TReturn operator()(TParam) = 0;
};
关于普通函数和类的静态成员函数,为了适应任何类型返回值, 任意类型参数,也需要使用模板,并继承IFun抽象类,代码如下
template <typename TReturn, typename TParam>
class CStaticFun : public IFun<TReturn, TParam>
{
typedef TReturn(*PFun)(TParam);
public:
explicit CStaticFun(PFun pFun) : m_pFun(pFun) {}
virtual TReturn operator()(TParam param) override
{
return m_pFun(param);
}
private:
PFun m_pFun;
};
同理关于类的成员函数也要用模板,代码如下
template <typename TObj, typename TReturn, typename TParam>
class CMemberFun : public IFun<TReturn, TParam>
{
typedef TReturn(TObj::*PFun)(TParam);
public:
explicit CMemberFun(TObj *pObj, PFun pFun) : m_pObj(pObj), m_pFun(pFun) {}
virtual TReturn operator()(TParam param) override
{
return (m_pObj->*m_pFun)(param);
}
private:
TObj *m_pObj;
PFun m_pFun;
};
为了提供给客户端良好的接口,因此再创建一个类类统一接口
template <typename TReturn, typename TParam>
class CFun : public IFun<TReturn, TParam>
{
public:
explicit CFun(TReturn(*pFun)(TParam)) : m_pFun(new CStaticFun<TReturn, TParam>(pFun)) {}
~CFun() { delete m_pFun; }
template <typename TObj>
explicit CFun(TObj *pObj, TReturn(TObj::*pFun)(TParam)) : m_pFun(new CMemberFun<TObj, TReturn, TParam>(pObj, pFun)) {}
virtual TReturn operator()(TParam param) override
{
assert(m_pFun);
return (*m_pFun)(param);
}
private:
IFun<TReturn, TParam> *m_pFun;
};
这样任意类型返回值,任意类型形参函数的委托基本上就完成了
下面是实例:
#include <iostream>
#include <cassert>
#include <string>
/*
* 把上面三个类的代码复制粘贴到这里
*/
bool fun(int i) { std::cout << "这是一个函数 i = " << i << std::endl; return false; }
class A
{
public:
explicit A() {}
static void fun1() { std::cout << "这是类的静态函数" << std::endl; }
void fun2(char c) { std::cout << "这是类的成员函数 c = " << c << std::endl; }
};
int main()
{
A a;
CFun<bool, int> f(fun);
//CFun<void, void> f1(&A::fun1); 因为这里必须要有一个参数,所以如果加入这一句编译不过,但返回值无所谓
CFun<void, char> f2(&a, &A::fun2);
CFun<int, double> lamda([](double a) -> int {
std::cout << "lamda a = " << a << std::endl;
return 0;
});
f(233333);
//f1();
f2('A');
lamda(3.1415);
return 0;
}
运行结果如下:
这是一个函数 i = 233333
这是类的成员函数 c = A
lamda a = 3.1415
下一次 将在这基础上实现任意返回类型,任意数量,任意类型形参的函数的委托(其实只需要利用到c++中的可变参数就可以做到这一点)