今天寫引擎的時候,很想加入一些回調函數,以前一直沒時間整理這塊,這次一定要下決心好好整整代碼,純粹用多態,很多類非要加個帽子,類之間的關系也顯的很單一,有的情況需要用到委托的回調機制,這是個很好的東西,在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約束方法,那么惡心的東西了吧

# 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 |
# 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 |
# re: 模版函數指針,C++委托的實現-原創 回復 更多評論
boost是很好,可有些龐大,目前并不打算使用
我已經加入了fastdelegate,這個短小精悍,足以解決我的問題了。
2008-10-06 22:14 |
# re: 模版函數指針,C++委托的實現-原創 回復 更多評論
聽說BOOST明年加入C++標準了!要慢慢去了解下!