举例
#include "head.h"
using namespace std;
int add(int x,int y){
return x + y;
}
class ADD{
public:
int operator()(int a,int b){
return a+b;
}
};
int main(){
function<int(int,int)> p = add;
cout << p(2,3) << endl;
ADD a;
function<int(int,int)> p1 = a;
cout << p1(2,3) << endl;
return 0;
}
输出为:
5
5
说明
cppreference手册
定义于头文件 <experimental/functional>
template< class >
class function; /* undefined */
(库基础 TS)
template< class R, class... Args >
class function<R(Args...)>
(库基础 TS)
std::experimental::function 是 std::function 的修改版本,支持类型擦除分配器。
例子分析
见举例代码
function<R(args…)> 可以指向函数。也可以指向类(带()操作符的),即函数对象
。
高级函数指针的用法就是函数指针,可以由普通函数指针赋值,也可以由函数对象的函数指针赋值。
自己实现高级函数指针
实现代码
#include "head.h"
using namespace std;
//-----构建FUNTION高级指针类----------------------------------
//基类 Base
template <typename T,typename ...ARGS>
class Base{
public:
virtual T run(ARGS... args) = 0;
virtual Base* getCopy() = 0;
};
//普通函数 - Base子类
template <typename T,typename ...ARGS>
class NormalFunc:public Base<T,ARGS...>{
public:
T (*ptr)(ARGS...);
public:
NormalFunc(T (*p)(ARGS...)):ptr(p){}
T run(ARGS ...args) override{
return ptr(forward<ARGS>(args)...);
//forward<ARGS>(args) 可变参的类型在函数调用保持不变(左右值引用),参数右值使用引用变成左值,此时就不希望改变它引用的对象,再去拷贝一个。
}
Base<T,ARGS...> *getCopy()override{
return new NormalFunc(*this);
}
};
//函数对象 - Base子类
template <typename CLASS_T,typename T, typename ...ARGS>
class FuncClass:public Base<T,ARGS...>{
private:
CLASS_T obj;
public:
FuncClass(CLASS_T &obj):obj(obj){}
T run(ARGS... args) override{
return obj(forward<ARGS>(args)...);
}
Base<T,ARGS...>* getCopy()override{
return new FuncClass(*this);
}
};
//功能类
//声名功能类
template <typename T,typename ...ARGS> class Function{};
//功能类特化
template <typename T,typename ...ARGS>
class Function<T(ARGS...)>{
private:
//属性只有一个就是Base类指针,用来指向函数对象或者普通函数
Base<T,ARGS...>* ptr;
public:
//普通函数去构造
Function(T (*p)(ARGS...)):ptr(new NormalFunc<T,ARGS...>(p)){}
//函数对象去构造
template <typename CLASS_T>
Function(CLASS_T obj):ptr(new FuncClass<CLASS_T,T,ARGS...>(obj)){}
//重载操作符()
T operator()(ARGS ...args){
return ptr->run(forward<ARGS>(args)...);
}
//赋值构造,进行深拷贝。
Function& operator=(const Function& f){
delete ptr;
//getCopy()是因为Base类会指向不同的东西,由这些对象提供一份自己的拷贝过来。
ptr = f.ptr->getcopy();
return *this;
}
//拷贝构造。
Function(const Function& f){
ptr = f.ptr->getCopy();
}
};
//-------猜测部分----------------------------------------
//普通函数
int add(int x,int y){
return x + y;
}
//函数对象
class ADD{
public:
int operator()(int a,int b){
return a+b;
}
};
int main(){
Function<int(int,int)> p = add;
cout << p(1,3) << endl;;
ADD a;
Function<int(int,int)> p1 = a;
cout << p1(2,3) << endl;
Function<int(int,int)> b(a);
cout << b(4,5) << endl;
return 0;
}
//--------------------------------------------------------
输出为:
4
5
9
分析
- 其本质是一个指针。
- 利用了模板,不定参和多态。
类间关系
- 基类
Base
为纯虚函数,两个子类(普通函数封装类NormalFunc
和 函数对象封装类FunctCalss
)继承Base。这里使用模板的继承。 - 我们要实现的功能类
Function
,基于NormalFunc
和FunctCalss
实现不同的构造。其operator()
方法调用基类Base
的run()
方法(在两个子类中被重载)。这里使用了多态。