C++中關(guān)于委派(Delegates)的實(shí)現(xiàn)示例
介紹
在 C++ 中通過(guò)一個(gè)全局函數(shù)來(lái)綁定到對(duì)象的成員函數(shù)是很有用的,這個(gè)特性也存在于其他語(yǔ)言中,例如 C#的委派。在 C++ 中相當(dāng)于成員函數(shù)指針,但是 并沒(méi)有提供相應(yīng)的特性。在這篇文章中,我想提出一個(gè)簡(jiǎn)單的 C++ 委派的實(shí)現(xiàn),是用 C++ 成員函數(shù)指針和 C++11 的可變模板(variadic templates),目前這套實(shí)現(xiàn)方法僅支持 GNU C++ 4.7.0,在 Windows 下可使用 MinGW。
背景
在我的方法中獎(jiǎng)提供一個(gè)create_delegate函數(shù),可通過(guò)下面兩種方法來(lái)調(diào)用:
create_delegate(&object, &member_function) create_delegate(&function)
第一種方法創(chuàng)建一個(gè)對(duì)象并提供一個(gè)operator()成員函數(shù),第二個(gè)方法生成一個(gè)函數(shù)指針,兩種方法都兼容 type function<...>.
示例程序
首先我們定義一個(gè)包含多個(gè)方法的類:
class A { int i; public: A(int k):i(k) {} auto get()const ->int { return i;} auto set(int v)->void { i = v;} auto inc(int g)->int& { i+=g; return i;} auto incp(int& g)->int& { g+=i; return g;} auto f5 (int a1, int a2, int a3, int a4, int a5)const ->int { return i+a1+a2+a3+a4+a5; } auto set_sum4(int &k, int a1, int a2, int a3, int a4)->void { i+=a1+a2+a3+a4; k = i; } auto f8 (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const ->int { return i+a1+a2+a3+a4+a5+a6+a7+a8; } static auto sqr(double x)->double { return x*x; } };
請(qǐng)注意你并不需要一定使用 C++ 的 auto 函數(shù)語(yǔ)法,你也可以使用傳統(tǒng)的方法,然后我們使用下面方法創(chuàng)建一個(gè)類:
A a(11);
接下來(lái)我們創(chuàng)建委派:
auto set1 = create_delegate(&a,&A::set); auto inc = create_delegate(&a,&A::inc); std::function<int(int&)> incp = create_delegate(&a,&A::incp); auto af5 = create_delegate(&a,&A::f5); auto set_sum4= create_delegate(&a,&A::set_sum4); auto af8 = create_delegate(&a,&A::f8); auto sqr = create_delegate(&A::sqr); // static function </int(int&)> set1(25); int x = 5; int k = inc(x); k = incp(x); std::cout << "a.get():" << a.get() << std::endl; std::cout << "k: " << k << std::endl; std::cout << "x: " << x << std::endl; std::cout << "af5(1,2,3,4,5): " << af5(1,2,3,4,5) << std::endl; set_sum4(x,1,2,3,20); std::cout << "after set_sum4(x,1,2,3,20)" << std::endl; std::cout << "a.get(): " << a.get() << std::endl; std::cout << "x: " << x << std::endl; std::cout << "af8(1,2,3,4,5,6,7,8): " << af8(1,2,3,4,5,6,7,8) << std::endl; std::cout << "sqr(2.1): " << sqr(2.1) << std::endl;
執(zhí)行上述程序的打印結(jié)果如下:
a.get():30 k: 35 x: 35 af5(1,2,3,4,5): 45 after set_sum4(x,1,2,3,20) a.get(): 56 x: 56 af8(1,2,3,4,5,6,7,8): 92 sqr(2.1): 4.41
關(guān)鍵點(diǎn)
對(duì)于一個(gè)不是 volatile 和 const 的簡(jiǎn)單函數(shù)而言,實(shí)現(xiàn)是非常簡(jiǎn)單的,我們只需要?jiǎng)?chuàng)建一個(gè)類保存兩個(gè)指針,一個(gè)是對(duì)象,另外一個(gè)是成員函數(shù):
template <class T, class R, class ... P> struct _mem_delegate { T* m_t; R (T::*m_f)(P ...); _mem_delegate(T* t, R (T::*f)(P ...) ):m_t(t),m_f(f) {} R operator()(P ... p) { return (m_t->*m_f)(p ...); } };
可變模板 variadic template 允許定義任意個(gè)數(shù)和類型參數(shù)的operator()函數(shù),而create_function 實(shí)現(xiàn)只需簡(jiǎn)單返回該類的對(duì)象:
template <class T, class R, class ... P> _mem_delegate<T,R,P ...> create_delegate(T* t, R (T::*f)(P ...)) { _mem_delegate<T,R,P ...> d(t,f); return d; }
實(shí)際中,我們需要另外的三個(gè)實(shí)現(xiàn)用于覆蓋 const、volatile 和 const volatile 三種成員函數(shù),這也是為什么傳統(tǒng)使用 #define 宏很便捷的原因,讓你無(wú)需重寫代碼段,下面是完整的實(shí)現(xiàn):
template <class F> F* create_delegate(F* f) { return f; } #define _MEM_DELEGATES(_Q,_NAME)\ template <class T, class R, class ... P>\ struct _mem_delegate ## _NAME\ {\ T* m_t;\ R (T::*m_f)(P ...) _Q;\ _mem_delegate ## _NAME(T* t, R (T::*f)(P ...) _Q):m_t(t),m_f(f) {}\ R operator()(P ... p) _Q\ {\ return (m_t->*m_f)(p ...);\ }\ };\ \ template <class T, class R, class ... P>\ _mem_delegate ## _NAME<T,R,P ...> create_delegate(T* t, R (T::*f)(P ...) _Q)\ {\ _mem_delegate ##_NAME<T,R,P ...> d(t,f);\ return d;\ } _MEM_DELEGATES(,Z) _MEM_DELEGATES(const,X) _MEM_DELEGATES(volatile,Y) _MEM_DELEGATES(const volatile,W)
上一篇:C語(yǔ)言按關(guān)鍵字搜索文件夾中文件的方法
欄 目:C語(yǔ)言
本文標(biāo)題:C++中關(guān)于委派(Delegates)的實(shí)現(xiàn)示例
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2971.html
您可能感興趣的文章
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)數(shù)怎么表達(dá)
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎么打出三角函數(shù)的值
- 01-10深入理解C++中常見(jiàn)的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10深入Main函數(shù)中的參數(shù)argc,argv的使用詳解
- 01-10APUE筆記之:進(jìn)程環(huán)境詳解
- 01-10c++中inline的用法分析
- 01-10如何尋找數(shù)組中的第二大數(shù)


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-11Mac OSX 打開(kāi)原生自帶讀寫NTFS功能(圖文
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10delphi制作wav文件的方法
- 04-02jquery與jsp,用jquery