C++中关于委派(Delegates)的实现示例

C++中关于委派(Delegates)的实现示例,第1张

概述 介绍在C++中通过一个全局函数来绑定到对象的成员函数是很有用的,这个特性也存在于其他语言中,例如C#的委派。在C++中相当于成员函数指针,但是并没有提供相应的特性。在这篇文章中,我想提出一个简单的C++委

 介绍

在 C++ 中通过一个全局函数来绑定到对象的成员函数是很有用的,这个特性也存在于其他语言中,例如 C#的委派。在 C++ 中相当于成员函数指针,但是 并没有提供相应的特性。在这篇文章中,我想提出一个简单的 C++ 委派的实现,是用 C++ 成员函数指针和 C++11 的可变模板(variadic templates),目前这套实现方法仅支持 GNU C++ 4.7.0,在 windows 下可使用 MinGW。

背景

在我的方法中奖提供一个create_delegate函数,可通过下面两种方法来调用:

  create_delegate(&object,&member_function)  create_delegate(&function)

第一种方法创建一个对象并提供一个operator()成员函数,第二个方法生成一个函数指针,两种方法都兼容 type function<...>.

示例程序

首先我们定义一个包含多个方法的类:
 

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 a4)->voID  {    i+=a1+a2+a3+a4;    k = i;  }   auto f8 (int a1,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; }};

请注意你并不需要一定使用 C++ 的 auto 函数语法,你也可以使用传统的方法,然后我们使用下面方法创建一个类:

 

A a(11);

接下来我们创建委派:
 

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,5) << std::endl; set_sum4(x,1,20);std::cout << "after set_sum4(x,20)" << std::endl;std::cout << "a.get(): " << a.get() << std::endl;std::cout << "x: " << x << std::endl;std::cout << "af8(1,5,6,7,8): " << af8(1,8) << std::endl;std::cout << "sqr(2.1): " << sqr(2.1) << std::endl;

 
执行上述程序的打印结果如下:
 

a.get():30k: 35x: 35af5(1,5): 45after set_sum4(x,20)a.get(): 56x: 56af8(1,8): 92sqr(2.1): 4.41

关键点
对于一个不是 volatile 和 const 的简单函数而言,实现是非常简单的,我们只需要创建一个类保存两个指针,一个是对象,另外一个是成员函数:
 

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 允许定义任意个数和类型参数的operator()函数,而create_function 实现只需简单返回该类的对象:

 

template <class T,class ... P>_mem_delegate<T,R,P ...> create_delegate(T* t,R (T::*f)(P ...)){  _mem_delegate<T,P ...> d(t,f);  return d;}

 
 

实际中,我们需要另外的三个实现用于覆盖 const、volatile 和 const volatile 三种成员函数,这也是为什么传统使用 #define 宏很便捷的原因,让你无需重写代码段,下面是完整的实现:
 

template <class F>F* create_delegate(F* f){  return f;}#define _MEM_DELEGATES(_Q,_name)\template <class T,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 ... P>\  _mem_delegate ## _name<T,R (T::*f)(P ...) _Q)\{\  _mem_delegate ##_name<T,f);\  return d;\} _MEM_DELEGATES(,Z)_MEM_DELEGATES(const,X)_MEM_DELEGATES(volatile,Y)_MEM_DELEGATES(const volatile,W)

总结

以上是内存溢出为你收集整理的C++中关于委派(Delegates)的实现示例全部内容,希望文章能够帮你解决C++中关于委派(Delegates)的实现示例所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1256270.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存