分享
 
 
 

一个C++ delegate的实现

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

最近需要一个C++delegate的实现,比较接近C#的delegate的用法。翻遍了boost,虽然有相近的东西,但是,始终使用起来问题多多:

function:的绑定方式倒也可以接受,成员函数调用的方式实在不爽。而且,同样的函数原型,native和member对应的function类型不同,不同class的相同原型的member function类型也不同。

signal:用起来不错,但是,一来内置了slot装置,又不便于介入干扰,二来,如何绑定一般的成员函数,不知道如何实现,只能绑定native function和functor。

bind:正是我所要的。可惜,占位符最大到3。

还有个siglib++的库,昨天才看到,为时已晚。粗略的看了一下,调用的方法,似乎也是拖泥带水。

不是我喜欢自己发明轮子,实在是迫不得已,只好自己写delegate了。手写的代码不长,贴在下面共享:

/*

copywrite: 别逗了(非典型秃子)

Description: C++的delegate实现。

可以随意复制、修改、分发、使用。不要说是自己的就可以了。^_^

*/

#ifndef DELEGATE_H

#define DELEGATE_H

#include "contract.h"//自己的一个库,只和下面的一些断言有关。

namespace nice

{

template<typename T>

class delegate;

//长长的宏,没办法:(

#define DELEGATE(TEMPLATE_ARGS, FUNCTION_ARGS, FUNCTION_PARA) template< typename Ret TEMPLATE_ARGS > class delegate<Ret (FUNCTION_ARGS)> { struct FunctionHolder { virtual Ret operator()(FUNCTION_ARGS) = 0; virtual FunctionHolder* clone() const = 0; virtual ~FunctionHolder(){}; }; FunctionHolder* h; template<typename Functor> struct FunctorHolder : public FunctionHolder { Functor* Fun; FunctorHolder(Functor* nfun) : Fun(nfun){} virtual Ret operator()(FUNCTION_ARGS) { return (*Fun)(FUNCTION_PARA); } virtual FunctionHolder* clone() const { return new FunctorHolder(*this); } }; template<typename U, typename MemFun> struct MemHolder : public FunctionHolder { U obj; MemFun memFun; MemHolder(U aObj, MemFun amfun) : obj(aObj), memFun(amfun){} virtual Ret operator()(FUNCTION_ARGS) { return ((*obj).*memFun)(FUNCTION_PARA); } virtual FunctionHolder* clone() const { return new MemHolder(*this); } }; FunctionHolder* cloneHolder() const { if (connected()) return h->clone(); return NULL; } public: delegate() : h(0) { } ~delegate() { disconnect(); } template<typename Functor> delegate(Functor* nfun_) : h(new FunctorHolder<Functor>(nfun_)) { } delegate(const delegate& rhs) : h(rhs.cloneHolder()) {} template <typename U, typename MemFun> delegate(U aObj, MemFun mFun) : h(new MemHolder<U, MemFun>(aObj, mFun)) { } delegate& operator=(const delegate& rhs) { if (&rhs != this) { disconnect(); h = rhs.cloneHolder(); } return *this; } template<typename Functor> void connect(Functor* nfun_) { disconnect(); h = new FunctorHolder<Functor>(nfun_); } template <typename U, typename MemFun> void connect(U aObj, MemFun mFun) { if (h) delete h; h = new MemHolder<U, MemFun>(aObj, mFun); } void disconnect() { if (connected()) delete h; h = 0; } bool connected() const { return (h != NULL); } Ret operator()(FUNCTION_ARGS) { pre_condition(connected()); return (*h)(FUNCTION_PARA); } };

//*/

#define TEMPLATE_ARGS_0

#define FUNCTION_ARGS_0

#define FUNCTION_PARA_0

#define TEMPLATE_ARGS_1 , typename T0

#define FUNCTION_ARGS_1 T0 t0

#define FUNCTION_PARA_1 t0

/* Defines Generate code:

for (int i = 2; i <= 50; i++)

{

printf("#define TEMPLATE_ARGS_%d TEMPLATE_ARGS_%d, typename T%d\n", i, i - 1, i - 1) ;

printf("#define FUNCTION_ARGS_%d FUNCTION_ARGS_%d, T%d t%d\n", i, i - 1, i - 1, i - 1);

printf("#define FUNCTION_PARA_%d FUNCTION_PARA_%d, t%d\n\n", i, i - 1, i - 1);

};

for (int i = 0; i <= 50; ++i)

printf("DELEGATE(TEMPLATE_ARGS_%d, FUNCTION_ARGS_%d, FUNCTION_PARA_%d)\n", i, i, i);

*/

//Auto Generate code:----------------------------------------------

#define TEMPLATE_ARGS_2 TEMPLATE_ARGS_1, typename T1

#define FUNCTION_ARGS_2 FUNCTION_ARGS_1, T1 t1

#define FUNCTION_PARA_2 FUNCTION_PARA_1, t1

....

#define TEMPLATE_ARGS_3 TEMPLATE_ARGS_2, typename T2

#define FUNCTION_ARGS_3 FUNCTION_ARGS_2, T2 t2

#define FUNCTION_PARA_3 FUNCTION_PARA_2, t2

#define TEMPLATE_ARGS_4 TEMPLATE_ARGS_3, typename T3

#define FUNCTION_ARGS_4 FUNCTION_ARGS_3, T3 t3

#define FUNCTION_PARA_4 FUNCTION_PARA_3, t3

...

DELEGATE(TEMPLATE_ARGS_0, FUNCTION_ARGS_0, FUNCTION_PARA_0)

DELEGATE(TEMPLATE_ARGS_1, FUNCTION_ARGS_1, FUNCTION_PARA_1)

DELEGATE(TEMPLATE_ARGS_2, FUNCTION_ARGS_2, FUNCTION_PARA_2)

DELEGATE(TEMPLATE_ARGS_3, FUNCTION_ARGS_3, FUNCTION_PARA_3)

...

};

#endif//end DELEGATE_H

测试用例:

CPPUNIT_TEST_SUITE_REGISTRATION(test_delegate);

using namespace nice;

int local_add(int a, int b)

{

return a + b;

}

struct functor_add

{

int m;

int mem_add(int a, int b)

{

return a + b + m;

}

};

struct functor_mul

{

int m;

int operator()(int a, int b)

{

return (a + b) * m;

}

};

void test_delegate::testMain()

{

typedef delegate<int(int, int)> testDele2;

//默认ctor没有连接上

testDele2 dele1;

CPPUNIT_ASSERT(!dele1.connected());

//connect

testDele2 dele2(local_add);

CPPUNIT_ASSERT(dele2.connected());

//调用

CPPUNIT_ASSERT(dele2(2, 3) == 5);

//copy ctor

testDele2 dele3 = dele2;

CPPUNIT_ASSERT(dele3.connected());

CPPUNIT_ASSERT(dele3(2, 3) == 5);

//disconnect

dele2.disconnect();

CPPUNIT_ASSERT(!dele2.connected());

//test clone

CPPUNIT_ASSERT(dele3.connected());

dele3(2, 3);

CPPUNIT_ASSERT(dele3(2, 3) == 5);

//assign

dele2 = dele3;

CPPUNIT_ASSERT(dele2(2, 3) == 5);

//member function

functor_add fctor;

fctor.m = 7;

dele2.connect(&fctor, &functor_add::mem_add);

CPPUNIT_ASSERT(dele2(2, 3) == 12);

//functor

functor_mul fm;

fm.m = 3;

testDele2 dele4(&fm);

CPPUNIT_ASSERT(dele4(2, 3) == 15);

fm.m = 4;

CPPUNIT_ASSERT(dele4(2, 3) == 20);

dele2.connect(&fm);

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有