3d Game Walkman

3d图形渲染,网络引擎 — tonykee's Blog
随笔 - 45, 文章 - 0, 评论 - 309, 引用 - 0
数据加载中……

模版函数指针,C++委托的实现-原创

今天写引擎的时候,很想加入一些回调函数,以前一直没时间整理这块,这次一定要下决心好好整整代码,纯粹用多态,很多类非要加个帽子,类之间的关系也显的很单一,有的情况需要用到委托的回调机制,这是个很好的东西,在C#里面是原生支持的,C++里面本来函数指针是个不错的选择,可到了对象里面,成员函数指针还有那么好用吗?这原本是另C++程序员非常失望和无赖的,难道一说到成员函数指针就真的那么不好用,甚至要沦为被唾弃的命运?并非入此,别忘了,C++里面还有很强的利器,C#和Java后天才具备的特性可是C++先天就具备的哦,那就是范型,C++里面的用的是模版,而且如果把 模版和成员函数指针结合在一起,那就威力无比了,那应该叫做就是“成员模版函数指针”,C++的教科书上有这个名词吗?我查了查,好像是没有,而且网上很多资料竟然说这个不能实现之类的话,我都怀疑那些如此断言的人是否太不负责仁了,误导人啊。

当然指想成员函数的指针,这里面的确有段C++设计的问题,C++的成员函数地址通过对象外去引用不能直接通过“&对象.方法”的方式来引用,这个在C++标准里面是没有的,很多人到这里就绝望了,可间接引用呢?而且用很优雅的方式来引用呢?

好了,我也不绕圈子了,给出我的代码,一个简单的 “成员模版函数指针” 的实现,看看C++是如何优雅的实现委托的,真的非常非常的优雅,由于完全自己摸索出来的,真是感慨万千啊。

#include "stdafx.h"

#include <iostream>

using namespace std;

template<typename T>
class A
{
private:
   typedef int (T::*delegateFun)(int);
   T * _This;
   delegateFun _deleGate;

public:   

 //This被代理的对象, delegateFun被代理的方法
 
 A(T * This, int (T::*delegateFun)(int))
 {
       _This = This;
       _deleGate = delegateFun;
 }

    //c被代理的参数
 int execue(int c)
 {
      return (_This->*_deleGate)(c);
 }

};


class B
{
public:
 int FunA(int a) {return a + 10;}
 int FunB(int a) {return a - 10;}
 B()
 {

 }
};

int _tmain(int argc, _TCHAR* argv[])
{


 B *objB = new B();

 A<B>  delegateObj1(objB, (&B::FunA));
 A<B>  delegateObj2(objB, (&B::FunB));


 cout << delegateObj1.execue(10) <<endl;
 cout << delegateObj2.execue(20) <<endl;

 return 0;

}

 

 

 

看完了感觉如何?以后想要设计一个callback回调函数是否明朗了许多?
再也不需要强行搞个static约束方法,那么恶心的东西了吧

 

posted on 2008-09-29 13:23 李侃 阅读(6728) 评论(14)  编辑 收藏 引用 所属分类: 杂谈

评论

# re: 模版函数指针,C++委托的实现-原创  回复  更多评论   

sigslot
2008-09-29 14:05 | 万连文

# re: 模版函数指针,C++委托的实现-原创[未登录]  回复  更多评论   

template<typename T>
int funA(T * This, int (T::*delegateFun)(int), int c)
{
return (This->*delegateFun)(c);
}
可以算做委托调用的基本原理,还需要保存This和delegateFun的值才能称之为委托。
2008-09-29 14:15 | noname

# re: 模版函数指针,C++委托的实现-原创  回复  更多评论   

做了一点点调整,这个应该就是了
2008-09-29 16:06 | 李侃

# re: 模版函数指针,C++委托的实现-原创[未登录]  回复  更多评论   

A<B> delegateObj1(objB, (&B::FunA));
在这里类A必须了解B的类型,而委托存在的意义在于委托类与被委托的对象之间的无关性,可以参照网上一篇关于fastdelegate的文章。
2008-09-29 22:24 | noname

# re: 模版函数指针,C++委托的实现-原创  回复  更多评论   

哈哈~楼主创造力不错!
我也干个类似的事,不过,比楼主还是再"过分"一些~:-P
楼上说得有道理,模板类的解耦是不完全的(虽然一般已经够用),使得A<B>类只能存放B的成员函数指针,A<C>类只能存放C的成员函数指针。
换一下思路,能否在一个对象里边托管多个属于不同的类的成员函数指针?
2008-09-29 23:03 | 踏雪赤兔

# re: 模版函数指针,C++委托的实现-原创  回复  更多评论   

fastdelegate 还可以,去研究一把
2008-09-30 11:45 | 李侃

# re: 模版函数指针,C++委托的实现-原创[未登录]  回复  更多评论   

非常不错!
强大的消息映射、状态机事件映射都要靠这个才能完美的解决成员函数的问题。
2008-09-30 12:46 | cppexplore

# re: 模版函数指针,C++委托的实现-原创  回复  更多评论   

A<B> delegateObj1(objB, (&B::FunA));
在这里类A必须了解B的类型,而委托存在的意义在于委托类与被委托的对象之间的无关性
-----------------------
这才是关键
2008-10-06 11:33 | adie

# re: 模版函数指针,C++委托的实现-原创  回复  更多评论   

boost中bind这样来做:
class button
{
public:

boost::function<void> onClick;
};

class player
{
public:

void play();
void stop();
};

button playButton, stopButton;
player thePlayer;

void connect()
{
playButton.onClick = boost::bind(&player::play, &thePlayer);
stopButton.onClick = boost::bind(&player::stop, &thePlayer);
}
2008-10-06 16:20 | Wang Feng

# re: 模版函数指针,C++委托的实现-原创  回复  更多评论   

boost是很好,可有些庞大,目前并不打算使用
我已经加入了fastdelegate,这个短小精悍,足以解决我的问题了。
2008-10-06 22:14 | 李侃

# re: 模版函数指针,C++委托的实现-原创  回复  更多评论   

听说BOOST明年加入C++标准了!要慢慢去了解下!
2008-10-07 16:48 | RichardHe

# re: 模版函数指针,C++委托的实现-原创  回复  更多评论   

使用fastdelegate, 很快, 也能解决成员函数的e问题, 还能进一步封装成多路委托, 非常方便
2009-01-11 12:23 | llxisdsh

# re: 模版函数指针,C++委托的实现-原创  回复  更多评论   

<B> delegateObj1(objB, (&B::FunA));
在这里类A必须了解B的类型,而委托存在的意义在于委托类与被委托的对象之间的无关性,
2011-04-30 16:34 | hcq11

# re: 模版函数指针,C++委托的实现-原创  回复  更多评论   

c#的委托原理就是c/c++函数指针,如果不能实现的话委托是怎么来的。function/bind嘛
2013-06-02 14:39 | momognu

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理