c++ 函数对象池实现

     由于本人要与舍友开发一个codeblock的vim插件,在我们的架构体系中,我们觉得用函数对象池要灵活且易于扩张的多,所以边写了个函数对象池,来管理应用程序中的功能性函数.这个函数对象池可一将一个函数,或者一个成员函数,转换为一个函数对象(Delegate)然后在存入池中,当池满的时候就会进行池的扩张的一些列的动作,大概行为和STL里面的内存池差不多. 

 

一下是实现代码:

 

//MyEvent.h

#ifndef MYEVENT_H_INCLUDED
#define MYEVENT_H_INCLUDED

#include <vector>
#include <list>
#include <iostream>
#include <typeinfo>
#include <iterator>

using namespace std;

namespace Zsh{

//用于判断对象池中是否已经有了类型和t一样的对象
template <typename T>
int ifind(vector<T> vec,int n,T t){
for(int i = 0;i<n;++i){
if(vec[i] == t)
return i;
}

return -1;
}


//用于查找对象池中可以使用的id号
template <typename T>
int mfind(list<T> v,const T& t){
typename list<T>::iterator ite = v.begin();

for(int i = 0;ite!=v.end();++ite,++i){
if(*ite == t){
return i;
}
}

return -1;
}

 

//主要用于实现Gelegate的第三个参数,如果传的使对象,那么该对象就要继承这个对象
class ArgObject{

};

//一个代理,相当于时间处理中的EventHandler
template<typename ReturnType,typename ArgsType,typename ObjectType = ArgObject>
class Delegate
{


   typedef enum {Object,Function} VarType;//是否用对象初始化的
   typedef ReturnType(*ObFunction)(void* ob,ArgsType);//相当不容易啊,用于解决对象成员指针的问题

public:

//以对象来初始化
template <typename RealObjectType>
Delegate(RealObjectType* _object,ReturnType(RealObjectType::*_function)(ArgsType))
:varType(Object),avail(true)
{
of = (ObFunction)(void*)_function;
myArg/*.oper*/.object = _object;
// myArg.oper.ofunction = _function;
}

//以一个函数来初始化
Delegate(ReturnType(*_function)(ArgsType))
:varType(Function),avail(true)
{
myArg.function = _function;
}

Delegate(){}


//函数操作符
ReturnType operator()(ArgsType args){

if(varType == Object)
{
return of(myArg/*.oper*/.object,args);
//return (myArg.oper.object->*(myArg.oper.ofunction))(args);
}else{
return (myArg.function)(args);
}
}


//用于判断两个Delegate是否相等,为了便于运用于标准库中
bool operator==(const Delegate& delegate) const{
bool result;
if(delegate.varType == this->varType){

if(this->varType == Object){
if((typeid(delegate.myArg/*.oper*/.object) == typeid(this->myArg/*.oper*/.object))&&
(this->/*myArg.oper.*/of/*unction*/ == delegate./*myArg.oper*/of/*unction*/)){
result = true;
}else{
result = false;
}

}else{
if(this->myArg.function == delegate.myArg.function){
result = true;
}else{
result = false;
}
}

}else{
result = false;
}


return result;
}

public:
void Enable(){
avail = true;
}


void Disable(){
avail = false;
}

bool isEnable(){
return avail;
}

private:

//定义自己的数据类型
//参数的联合体
union OperArg{
// struct Oper{
// ObjectType* object;
// ReturnType(ObjectType::*ofunction)(ArgsType);
// };
// Oper oper;

ObjectType* object;
ReturnType(*function)(ArgsType);
};

 

//类的私有成员定义
private:
VarType varType;//实例化参数的类型,是函数指针,还是成员函数指针
OperArg myArg;

ObFunction of;

private:
bool avail;//用于软删除时作标记
};

 

 


template<typename ReturnType = void,typename ArgsType = void*>
class OperaTable
{
public:
typedef Delegate<ReturnType,ArgsType> Handler;
typedef vector<Handler> OpTable;
typedef size_t TableId;

public:
OperaTable(const size_t _size):size(_size),opTable(_size){
for(size_t i = 0;i<size;++i)
availableIds.push_back(i);
}


//添加一个Operator对象到池中,返回的是函数对象池中的一个id
TableId addOperator(Handler& handler){

int ite = ifind(opTable,opTable.size(),handler);

if(ite == -1){

//请求新的资源
int id = RequestId();

//将对象放入缓冲池中
if(id != -1){
opTable[id] = handler;
}

--current;
return id;
}else{

//池中已经有了此对象,且可用
if(opTable[ite].isEnable()){
return -1;
}else{
//池中已经有了此对象,但是进行了软删除
opTable[ite].Enable();
--current;
return ite;
}
return -1;
}
}

 

//从池中删除一个Operator对象
bool deleteOperator(TableId id){

int rid;

if(opTable.size() > id){

//查看id是在使用
rid = mfind(availableIds,id);

//已经在使用
if(rid == -1){
// cout<<"delete object"<<endl;
availableIds.push_back(id);
opTable[id].Disable();
++current;
return true;
//无人使用
}else{
return false;
}

}else{
return false;
}

}

//重载了函数操作符
ReturnType operator()(TableId id,ArgsType args){
return opTable[id].operator()(args);
}

//返回池的大小
size_t Size() const throw(){
return size;
}

//返回池现在用了多少个资源
size_t userdSize() const throw(){
return current;
}

private:
TableId RequestId(){

TableId id = -1;

// 池中已经没有了可用的资源了
if(availableIds.empty()){
ReSize();
}

//返回资源Id
id = availableIds.front();
//资源号为Id的资源不可用了
availableIds.pop_front();

return id;
}


void ReSize(){
availableIds.resize(size<<1);
for(size_t i = size ; i< size<< 1 ; ++i){
availableIds.push_back(i);
}

opTable.resize(size<<1);

size = size<<1;
}

  //for test 打印池中的可用资源号用于测试
public:
void printAvailableId(){
copy(availableIds.begin(),availableIds.end(),ostream_iterator<int>(cout," "));
}

private:
size_t size;//记录池的大小
size_t current;//记录池已经使用的资源

OpTable opTable;
list<TableId> availableIds;
};

}

#endif // MYEVENT_H_INCLUDED

 


//main.cpp

 

#include <iostream>
#include "MyEvent.h"

using namespace std;
using namespace Zsh;

int function(int){
cout<<"hello world"<<endl;

return 0;
}

 

class test:public ArgObject{//如果传的成员函数指针,着这个类就必需继承ArgObject
public:
int say(int){

cout<<"hello zsh"<<endl;

a = 1;
b = a<<1;

cout << b<<endl;
if(b == 2){
tmp = "hello jiang li";
cout<<tmp<<endl;
}

return 0;
}

int a;

int b;

string tmp;

};


typedef void (*func_type)(void * obj, int num);

int main()
{
test t;
// int (test::*a)(int) = &test::say;
// void *p = (void*)a;
// int (*p1)(int) = ((int (*)(int))p);
// func_type pa = (func_type)p1;//&test::say;
// pa(&t,1);

OperaTable<int,int> table(10);

Delegate<int,int> opera(function);
Delegate<int,int> opera2(&t,&test::say);

int id = table.addOperator(opera);
table.printAvailableId();

cout<<endl;
int id2 = table.addOperator(opera2);
table.printAvailableId();
cout<<endl;

table(id,1);
table(id2,1);

table.deleteOperator(id2);
table.printAvailableId();

return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值