写自己的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