C++实现.NET气势的拜托[VC/C++编程]
本文“C++实现.NET气势的拜托[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
引言
在.NET中,拜托被用来实现事件处理.它答应一个类(办法)先注册一个事件,然后当此事件被引发时此注册的办法就会被调用.在非.Net环境的C++中,这并非一件简单的事,特别是类的非静态成员函数,要做为回调函数就更艰难了.本文的目标就是给出一种办理筹划, 使类的静态成员函数,非静态成员函数,还有类非成员函数都能像回调函数一样利用.这个实现非常器重范例安全,为了保持范例安全我们省去了某些特点的实现.
什么是拜托?
.NET框架中对拜托的定义以下:
"拜托是一个可以保持对某个办法引用的类.差别于别的类,拜托类有自己的签名(返回值,参数范例,个数),并且只能引用与其签名匹配的办法.拜托其实可以当作一个范例安全的函数指针或回调函数.
一个供应了拜托的类答应别的函数或类在此拜托上注册事件处理函数.然后当这个类的拜托被履行时,就会遍历其处理函数列表,一一调用,并传入传给拜托的信息.而供应拜托的那个类不需求知道拜托注册了多少处理函数,拜托自己会处理这一切.
正文
函数对象(functor)概述
我们用函数对象(functor, function object)来实现C++中的拜托.这答应一个非静态成员函数能在特定对象的环境中被调用.我们用模板技术来保证任何类范例都能在其上利用.一个基本的函数对象(functor)定义以下:
template<class T>
class Functor
{
public:
// Constructor takes the values and stores them
Functor(T *pObj, int (T::*pFunc)(int))
{
m_pObject = pObj;
m_pFunction = pFunc;
}
// Invokes the stored function
intoperator ()(int p)
{
return (m_pObject->*m_pFunction)(p);
}
private:
T *m_pObject; // Pointer to the object
int (T::*m_pFunction)(int); // Pointer to the function
};
这个函数对象(functor)利用的函数格局为:返回范例为int,带一个范例为int的参数.操作符operator ()是函数对象的关键.它使一个函数对象(functor)利用起来和函数调用一样.它的工作就是每次履行时调用保存在类内部的函数指针.以下代码展示了若何利用这个函数对象(functor):
class MyClass
{
public:
int Square(int p) { return p * p; };
};
void some_function()
{
// Create a class to call in the context of
MyClass theClass;
// Create and initialise the functor object
Functor<MyClass> myFunc(&theClass, MyClass::Square);
// Call the functor using the overloaded () operator
int result = myFunc(5);
// result will hold the value 25
}
由于重载了operator ()运算符,调用函数对象(functor)几近就和调用该函数本身一样便利.这里说“几近”是因为指向实际对象的指针并没有被显示利用-它被存放在函数对象(functor)内部利用.
的确,这很不错,但是我们为什么要利用函数对象(functor),而不是函数本身呢?很好的问题,当你知道你要调用的函数的签名(返回值和参数)而不关心其能否是类的成员函数,是哪个类的成员函数时,函数对象就非常的有效(译注:将这一信息部分化在对象内部,从而以统一的方法来调用全部具有相同签名的函数)看以下代码,我将它们划分成几项以便理解:
首先,是一个用纯虚基类来表示的一个以一个int为参数,返回值为int的函数对象.它只有一个函数,虚拟的operator()操作符,这样,我们便可以在不知道某函数对象实例的实际对象范例的情形下调用函数对象(functor)了.
// Abstract base class
class Functor
{
public:
// Invoke the functor (no implementation here as it must be overridden)
virtualintoperator()(int) = 0;
};
下面就是一个可以被实例化为任何类范例的模板类,假定它也有一个以一个int为参数,返回为int的函数.它是从Functor派生来的,所以一个指向特定函数对象的指针可以传给任何一个需求其基类对象(Functor)指针的地方,所以此函数对象可以不管其真正的对象范例而被调用.除了基类和类名,这个类与之前给出的类是完好一样的:
// Template functor
template<class T>
class TemplateFunctor : public Functor
{
public:
// Constructor takes the values and stores them
TemplateFunctor(T *pObj, int (T::*pFunc)(int))
{
m_pObject = pObj;
m_pFunction = pFunc;
}
// Invokes the stored function (overrides Functor::operator ())
intoperator ()(int p)
{
return (m_pObject->*m_pFunction)(p);
}
private:
T *m_pObject; // Pointer to the object
int (T::*m_pFunction)(int); // Pointer to the function
};
下面是一个以函数对象指针和该函数的参数为参数的简单函数,用来调用该函数对象.注意这里以基类Functor指针而不是派生模板类指针为参数.这是必须的, 因为每一个差别的模板参数产生的模板类都是差别的范例,直接用此模板类为参数就不能支持多种范例了.
int OperateOnFunctor(int i, Functor *pFunc)
{
if(pFunc)
return (*pFunc)(i);
else
return0;
}
这是一个简单的类,它包含了一个符合函数对象要求的函数-以一个int为参数并返回一个int.注意此函数还用到了一个该类的数据成员,这阐明这个回调函数实际应当是在实例对象的环境下被履行的, 所以引用同一类差别对象的函数对象会产生差别的后果:
class ClassA
{
public:
ClassA(int i) { m_Value = i; }
int FuncA(int i)
{
return (m_Value - i);
}
int m_Value;
};
以上是“C++实现.NET气势的拜托[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |