亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

在C++中實現.NET風格的委托

2019-11-17 05:48:24
字體:
來源:轉載
供稿:網友
引言

  在.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;
};
  這是一個簡單的程序,它創建兩個引用同一類類型的函數對象的實例,針對兩個同類型的不同的對象實例調用函數對象,并顯示結果.

int main()
{
ClassA a(20);
ClassA b(10);

TemplateFunctor<ClassA> functorA(&a, ClassA::FuncA);
TemplateFunctor<ClassA> functorB(&b, ClassA::FuncA);

cout << "a gives the value " << OperateOnFunctor(5, &functorA) << endl;
cout << "b gives the value " << OperateOnFunctor(5, &functorB) << endl;

return0;
}
  產生結果如下:

a gives the value 15
b gives the value 5
  在這個例子中,兩個函數對象都調用了ClassA::FuncA, 但是針對不同的對象.一個相似但又有些不同的例子是針對不同的類調用函數對象,假設我們實現了一個ClassB如下:

class ClassB
{
public:
ClassB(int i) { m_Value = i; }
int FuncB(int i)
{
return (m_Value + i); // + instead of -
}
int m_Value;
};
  假如我們的main函數實現如下,得到的結果就會有所不同:

int main()
{
ClassA a(20);
ClassB b(10);

TemplateFunctor<ClassA> functorA(&a, ClassA::FuncA);
TemplateFunctor<ClassB> functorB(&b, ClassB::FuncB);

cout << "a gives the value " << OperateOnFunctor(5, &functorA) << endl;
cout << "b gives the value " << OperateOnFunctor(5, &functorB) << endl;

return0;
}
  結果如下:

a gives the value 15
b gives the value 15
  這個例子中,functorB調用了ClassB::FuncB,因此結果是(10+5)。注重我們幾乎用同樣的方式把兩個函數對象傳給了OperateOnFunctor)。是基類Functor的設計提供了我們這種方便性。 用宏參數化函數對象

  所以函數對象是非常方便的東西,但是假如我們需要不同的參數或返回類型,我們就不得不重寫這些類, 這比較頭痛。幸好,我們可以利用宏的特性使這個變的簡單。也許會有人說這樣是過份使用宏,但這工作的很好,而且,在模板答應我們修改函數原型前,這是唯一的解決方案。

  因此我們定義了以下宏:

Collapse
#define DECLARE_FUNCTOR(name, parmdecl, parmcall) /
/* A function object base class for this parameter list */ /
class name##Functor /
{ /
public: /
virtualvoidoperator () parmdecl = 0; /
}; /
/
/* Template class derived from Functor for /
make class-specific function objects */ /
template<class C> /
class name##TFunctor : public name##Functor /
{ /
public: /
/* Only constructor - stores the given data */ /
name##TFunctor(C* pObj, void (C::*pFunc)parmdecl) /
{ /
m_pObj = pObj; /
m_pFunc = pFunc; /
} /
/
/* Invokes the function object with the given parameters */ /
voidoperator ()parmdecl { (m_pObj->*m_pFunc)parmcall; } /
C *m_pObj; /* Object pointer */ /
void (C::*m_pFunc)parmdecl; /* Method pointer */ /
};
  3個宏參數的意義如下:

  name -函數對象的名字。Functor基類會加上“Functor“的后綴, 而模板類會加上”TFunctor“的后綴。

  parmdecl -操作符operator()的參數列表聲明.列表必須包括在小括號對里面

  parmcall -傳給內部函數的實參列表。以下例子可以很好的解釋這兩個列表的關系:

  使用該宏的例子:

DECLARE_FUNCTOR(Add, (int p1, int p2), (p1, p2))
  定義了一個以2個int為參數函數對象AddFunctor。宏展開后代碼如下(當然, 事實上它們應該在一行上,并且沒有注釋)

Collapse
/* A function object base class for this parameter list */
class AddFunctor
{
public:
virtualvoidoperator () (int p1, int p2) = 0;
};

/* Template class derived from AddFunctor for
make class-specific function objects */
template<class C>
class AddTFunctor : public AddFunctor
{
public:
/* Only constructor - stores the given data */
AddTFunctor(C* pObj, void (C::*pFunc)(int p1, int p2))
{
m_pObj = pObj;
m_pFunc = pFunc;
}

/* Invokes the function object with the given parameters */
voidoperator ()(int p1, int p2) { (m_pObj->*m_pFunc)(p1, p2); }
C *m_pObj; /* Object pointer */
void (C::*m_pFunc)(int p1, int p2); /* Method pointer */
};
  正如你所看到的,在所有name出現的地方都被“Add“所代替, parmdecl則被(int P1, int p2)替換, 而parmcall則被(p1, p2)替換)。為了更好的體現parmdecl和parmcall的關系,看以下operator()操作符,第一行是宏, 第二行是展開后的代碼:

voidoperator ()parmdecl { (m_pObj->*m_pFunc)parmcall; }
voidoperator ()(int p1, int p2) { (m_pObj->*m_pFunc)(p1, p2); }
  parmdecl是函數參數列表的聲明,而parmcall是函數調用時的實參.遺憾的是,我們沒有辦法用宏來自動生成這些.這種實現有些不是那么優雅, 但它可以很好的工作,并且保證了函數的類型安全

  委托的實現

  委托的實現類似于函數對象,但委托存儲了一個函數對象的列表,當委托被調用時就會遍歷調用這個列表中的函數對象,而不是只有一個函數對象。這意味著假如需要的話,我們可以存儲,調用多個處理函數。類的定義如下(沒有包括實現代碼)。我沒有加入functor的定義因為上面已經定義過了。函數對象實際上也會在這個宏當中定義,在這個名字空間中:

Collapse
#define DECLARE_DELEGATE(name, parmdecl, parmcall) /
namespace name##Delegate /
{ /
class Delegate /
{ /
public: /
Delegate(); /
~Delegate(); /
/
/* Template function for adding member function callbacks */ /
template<class C> /
void Add(C *pObj, void (C::*pFunc)parmdecl); /
/* Add a non-member (or static member) callback function */ /
void Add(void (*pFunc)parmdecl); /
/* Template function for removing member function callbacks */ /
template<class C> /
void Remove(C *pObj, void (C::*pFunc)parmdecl); /
/* Removes a non-member (or static member) callback function */ /
void Remove(void (*pFunc)parmdecl); /
/
/* Addition operators */ /
voidoperator +=(Functor *pFunc); /
voidoperator +=(void (*pFunc)parmdecl); /
/* SuBTraction operators */ /
template<class C> /
voidoperator -=(TFunctor<C> *pFunc); /
voidoperator -=(void (*pFunc)parmdecl); /
/
/* Calls all the callbacks in the callback list */ /
void Invoke parmdecl; /
/* Calls all the callbacks in the callback list */ /
voidoperator ()parmdecl; /
/
private: /
/* List of callback functions */ /
std::vector<Functor*> m_pFuncs; /
/* typedef'd iterator */ /
typedef std::vector<Functor*>::iterator vit; /
}; /
} 一些重點

  委托和函數對象類都放在它們自己的名字空間中,所以它們是一個易治理的整體。

  函數對象存在一個STL vector中。vector包含了指向基類Functor的指針,所以它可以包含任何類型的模板函數對象的實例。當然, 還有一個函數對象沒有被列出來,這是用來包裝非類成成員函數或類的靜態成員函數的。它們功能上大致相同,只是它不需要保存一個對象指針,或要求函數是類的一部份
我們有兩種方法來調用委托的函數對象-Invoke函數或operator()操作符.兩種方法的效果完全相同,實際上()操作符內部調用了Invoke來實現。

  有兩種方法從委托增加,刪除回調函數.用Add()/Remove方法,或者用+=/-=運算符。同Invoke()/operator()一樣,這兩種方法在功能上相同-操作符直接調用非操作符方法。這兩種方法均有兩個重載,一個用來接收非靜態類成員函數,一個用來接收非類成員函數或者類靜態成員函數。

  還有一個用來創建函數對象的非成員函數沒有列出來,其創建出來的對象用來傳給+=和-=操作符函數。此函數并沒有被放在該類所在的名字空間中,其名字為傳給宏DECLARE_DELEGATE的name加上“Handler“的后綴,例如:

DECLARE_DELEGATE(Add, (int p1, int p2), (p1, p2))
  將會給出如下的函數原型:

template<class C>
AddDelegate::TFunctor<C> *AddHandler(C *pObj,
void (C::*pFunc)(int p1, int p2));
  如何使用

  展示如何使用這些代碼的最好方法就是給出一個例子。以下例子定義了一個以int, float為參數的委托。并定義了兩個簡單的類和其相應函數,當然, 也使用了一個靜態成員函數與一個非成員函數

Collapse
DECLARE_DELEGATE(Add, (int p1, float p2), (p1, p2))

class A
{
public:
A() { value = 5; }
virtualvoid Fun1(int val, float val2)
{
value = val*2*(int)val2;
cout << "[A::Fun1] " << val << ", " << val2 << endl;
}
staticvoid StaticFunc(int val, float val2)
{
cout << "[A::StaticFunc] " << val << ", " << val2 << endl;
}
public:
int value;
};

class B : public A
{
public:
void Fun1(int val, float val2)
{
value += val*3*(int)val2;
cout << "[B::Fun1] " << val << ", " << val2 << endl;
}
};

void GlobalFunc(int val, float val2)
{
cout << "[GlobalFunc] " << val << ", " << val2 << endl;
}

int main()
{
// Create class instances
A a;
B b;
// Create an instance of the delegate
AddDelegate::Delegate del;
// Add our handlers
del += AddHandler(&a, A::Fun1); // or del.Add(&a, A::Fun1);
del += AddHandler(&b, B::Fun1); // or del.Add(&b, B::Fun2);
del += GlobalFunc; // or del.Add(GlobalFunc);
del += A::StaticFunc; // or del.Add(A::StaticFunc);
// Invoke the delegate
del(4, 5); // or del.Invoke(4, 5);
// Print the class values
cout << "[main] a.value = " << a.value << endl;
cout << "[main] b.value = " << b.value << endl;
// Remove some of the handlers
del -= AddHandler(&a, A::Fun1); // or del.Remove(&a, A::Fun1);
del -= A::StaticFunc; // or del.Remove(A::StaticFunc);
// Invoke the delegate again
del(4, 5); // or del.Invoke(4, 5);
// Print the class values
cout << "[main] a.value = " << a.value << endl;
cout << "[main] b.value = " << b.value << endl;
return0;
}
  這個例子展示了委托幾乎所有的操作,其結果如下:

[A::Fun1] 4, 5
[B::Fun1] 4, 5
[GlobalFunc] 4, 5
[A::StaticFunc] 4, 5
[main] a.value = 40
[main] a.value = 65
[B::Fun1] 4, 5
[GlobalFunc] 4, 5
[main] a.value = 40
[main] b.value = 125
  代碼用了stl.h文件(由Oskar Weiland編寫)來去除編譯stl時的警告信息,這個文件包含在zip文件中,當然也可以從這兒得到??上螺d的代碼包括delegate.h和以上給出的例子代碼 QQread.com 推出Windows2003教程 win2003安裝介紹 win2003網絡優化 win2003使用技巧 win2003系統故障 服務器配置 專家答疑
更多的請看:http://www.qqread.com/windows/2003/index.Html類幫助

  因為代碼是由DECLARE_DELEGATE定制的, 這里我用<parameters>來表示你傳入的參數)

Method: template<class C> void Delegate::Add(C *pObj, void (C::*pFunc)(<parameters>))
Description: Adds a callback function that is a non-static member function of a class. The member function must return void and take a parameter list that is the same as <parameters>.
Return value: void - nothing.
Parameters: pObj - A pointer to the object to call the callback method in the context of.
pFunc - A pointer to the callback method to call.

Method: void Delegate::Add(void (*pFunc)(<parameters>))
Description: Adds a callback function that is either a static member function of a class or is not a class member function. The function must return void and take a parameter list that is the same as <parameters>.
Return value: void - nothing.
Parameters: pFunc - A pointer to the callback function to call.

Method: template<class C> void Delegate::Remove(C *pObj, void (C::*pFunc)parmdecl)
Description: Removes a callback function from the callback function list
Return value: void - nothing.
Parameters: pObj - A pointer to the object that is being referred to.
pFunc - A pointer to the callback method being referred to.
These two parameters together specify the callback handler to be removed.

Method: void Delegate::Remove(void (*pFunc)parmdecl)
Description: Removes a callback function from the callback function list
Return value: void - nothing.
Parameters: pFunc - A pointer to the callback method being referred to.

Method: void Delegate::operator +=(Functor *pFunc)
Description: Adds a callback function that is a non-static member function of a class. The member function must return void and take a parameter list that is the same as <parameters>.
Return value: void - nothing.
Parameters: pFunc - A pointer to the functor to call. This should be created using the <name>Handler() function.

Method: void Delegate::operator +=(void (*pFunc)(<parameters>))
Description: Adds a callback function that is either a static member function of a class or is not a class member function. The function must return void and take a parameter list that is the same as <parameters>.
Return value: void - nothing.
Parameters: pFunc - A pointer to the callback function to call.

Method: void Delegate::operator -=(Functor *pFunc)
Description: Removes a callback function that is a non-static member function of a class.
Return value: void - nothing.
Parameters: pFunc - A pointer to the functor to remove. This should be created using the <name>Handler() function, and is deleted by the function.

Method: void Delegate::operator -=(void (*pFunc)(<parameters>))
Description: Removes a callback function that is either a static member function of a class or is not a class member function.
Return Value: void - nothing.
Parameters: pFunc - A pointer to the callback function to remove.

Method: void Delegate::Invoke(<parameters>)
Description: Calls all the callbacks in the callback list with the specified parameters.
Return Value: void - nothing.
Parameters: <parameters> - The parameters to pass to the callback functions, as specified in the parameter to DECLARE_DELEGATE().

Method: void Delegate::operator ()(<parameters>)
Description: Calls all the callbacks in the callback list with the specified parameters
Return Value: void - nothing.
Parameters: <parameters> - The parameters to pass to the callback functions, as specified in the parameter to DECLARE_DELEGATE().
  后續功能

  增加一個宏-參數化的類來支持返回類型,為委托中每個函數對象存儲返回值用以之后訪問。

  加一些支持固定參數個數的模板類,如只帶一個參數的類,或只帶兩個參數的類等),這可能需要或不需要在量的類來實現-為委托的返回值或其它功能提供不同類型的類。 QQread.com 推出Windows2003教程 win2003安裝介紹 win2003網絡優化 win2003使用技巧 win2003系統故障 服務器配置 專家答疑
更多的請看:http://www.qqread.com/windows/2003/index.html建議?

  History

  版本信息

  2003-8-19-初始版本
 
  代碼文件

///////////////////////////////////////////////////////////////////////////
// delegate.h
// Interface/implementation of the delegate classes and macros
///////////////////////////////////////////////////////////////////////////
// Author: Ryan Binns
// Changelog:
// 19-Aug-2003 : Initial Release
///////////////////////////////////////////////////////////////////////////

#ifndef DELEGATE_H__
#define DELEGATE_H__

// This STL include file removes the STL warning when the compiler
// is set to warning level 4. It was written by Oskar Wieland, and
// is available at:
// http://www.codeproject.com/vcpp/stl/stl_without_warnings.asp
#define STL_USING_VECTOR
/*
* Here, for convenience, I just ignore this header file but put the code directly.
*/
//#include "stl.h"
#ifdef STL_USING_VECTOR

#pragma warning(push)

#include <yvals.h> // warning numbers get enabled in yvals.h

#pragma warning(disable: 4018) // signed/unsigned mismatch
#pragma warning(disable: 4100) // unreferenced formal parameter
#pragma warning(disable: 4245) // conversion from 'type1' to 'type2', signed/unsigned mismatch
#pragma warning(disable: 4663) // C++ language change: to eXPlicitly specialize class template 'vector'
#pragma warning(disable: 4702) // unreachable code
#pragma warning(disable: 4710) // 'function' : function not inlined
#pragma warning(disable: 4786) // identifier was truncated to 'number' characters in the debug information

#include <vector>

#pragma warning(pop)

#endif

// Declares a delegate
// name - gives the beginning of the name of the delegate namespace, so
// DECLARE_DELEGATE(Add, ..., ...) would make a namespace
// called "AddDelegate" which contains the Add delegate classes.
// parmdecl - is the declaration of the parameters in the callbacks
// (surrounded by brackets), such as "(int val1, int val2)"
// parmcall - is how the parameters are called (surrounded in brackets),
// such as "(var1, var2)"
// so: DECLARE_DELEGATE(Add, (int val1, int val2), (val1, val2))
// would declare a delegate called AddDelegate, that takes two int
// parameters (the parameter names are not important).
#define DECLARE_DELEGATE(name, parmdecl, parmcall)
namespace name##Delegate
{
class Delegate; /* Forward declaration */
/* A function object base class for this parameter list */
class Functor
{
public:
virtual void Invoke parmdecl = 0;
virtual bool isMethod() = 0;
virtual bool operator ==(Functor *pf) = 0;
};

/* Template class derived from Functor for
making class-specific function objects */
template<class C>
class TFunctor : public Functor
{
public:
/* Only constructor - stores the given data */
TFunctor(C* pObj, void (C::*pFunc)parmdecl)
{
m_pObj = pObj;
m_pFunc = pFunc;
}
bool isMethod() { return true; }
bool operator ==(Functor *pf)
{
if(!pf->isMethod())
return false;
TFunctor<C> *pf1 = (TFunctor<C>*)pf;
if((pf1->m_pObj == m_pObj) && (pf1->m_pFunc == m_pFunc))
return true;
else
return false;
}

/* Invokes the function object with the given parameters */
void Invoke parmdecl { (m_pObj->*m_pFunc)parmcall; }
private:
C *m_pObj; /* Object pointer */
void (C::*m_pFunc)parmdecl; /* Method pointer */
};

/* Class for function function objects */
class FFunctor : public Functor
{
public:
/* Only constructor - stores the given data */
FFunctor(void (*pFunc)parmdecl) { m_pFunc = pFunc; }
bool isMethod() { return false; }
bool operator ==(Functor *pf)
{
if(pf->isMethod())
return false;
FFunctor *pf1 = (FFunctor*)pf;
if(pf1->m_pFunc == m_pFunc)
return true;
else
return false;
}

/* Invokes the function object with the given parameters */
void Invoke parmdecl { m_pFunc parmcall; }
private:
void (*m_pFunc)parmdecl; /* Function pointer */
};

/* Delegate class definition */
class Delegate
{
public:
Delegate() { };
~Delegate()
{
for(vit i=m_pFuncs.begin(); i!=m_pFuncs.end(); i++)
delete (*i);
m_pFuncs.clear();
}

/* Template function for adding member function callbacks */
template<class C>
void Add(C *pObj, void (C::*pFunc)parmdecl)
{
m_pFuncs.push_back(new TFunctor<C>(pObj, pFunc));
}
/* Add a non-member (or static member) callback function */
void Add(void (*pFunc)parmdecl)
{
m_pFuncs.push_back(new FFunctor(pFunc));
}
/* Template function for removing member function callbacks */
template<class C>
void Remove(C *pObj, void (C::*pFunc)parmdecl)
{
TFunctor<C> f(pObj, pFunc);
for(vit i=m_pFuncs.begin(); i!=m_pFuncs.end(); i++)
{
if(*(*i) == &f)
{
delete *i;
m_pFuncs.erase(i);
break;
}
}
}
/* Removes a non-member (or static member) callback function */
void Remove(void (*pFunc)parmdecl)
{
FFunctor f(pFunc);
for(vit i=m_pFuncs.begin(); i!=m_pFuncs.end(); i++)
{
if(*(*i) == &f)
{
delete *i;
m_pFuncs.erase(i);
break;
}
}
}

/* Addition operators */
void operator +=(Functor *pFunc)
{
m_pFuncs.push_back(pFunc);
}
void operator +=(void (*pFunc)parmdecl)
{
m_pFuncs.push_back(new FFunctor(pFunc));
}
/* Subtraction operators */
void operator -=(Functor *pFunc)
{
for(vit i=m_pFuncs.begin(); i!=m_pFuncs.end(); i++)
{
if(*(*i) == pFunc)
{
delete *i;
m_pFuncs.erase(i);
break;
}
}
delete pFunc;
}
void operator -=(void (*pFunc)parmdecl)
{
Remove(pFunc);
}

/* Calls all the callbacks in the callback list */
void Invoke parmdecl
{
for(vit i=m_pFuncs.begin(); i!=m_pFuncs.end(); i++)
(*i)->Invoke parmcall;
}
/* Calls all the callbacks in the callback list */
void operator ()parmdecl { Invoke parmcall; }

private:
/* List of callback functions */
std::vector<Functor*> m_pFuncs;
/* typedef'd iterator */
typedef std::vector<Functor*>::iterator vit;
};
}

template<class C>
name##Delegate::TFunctor<C> *name##Handler(C *pObj, void (C::*pFunc)parmdecl)
{
return new name##Delegate::TFunctor<C>(pObj, pFunc);
}

#endif // DELEGATE_H__

#include <iostream>
#include "delegate.h"
using namespace std;

DECLARE_DELEGATE(Add, (int p1, float p2), (p1, p2))

class A
{
public:
A() { value = 5; }
virtual void Fun1(int val, float val2)
{
value = val*2*(int)val2;
cout << "[A::Fun1] " << val << ", " << val2 << endl;
}
static void StaticFunc(int val, float val2)
{
cout << "[A::StaticFunc] " << val << ", " << val2 << endl;
}
public:
int value;
};

class B : public A
{
public:
void Fun1(int val, float val2)
{
value += val*3*(int)val2;
cout << "[B::Fun1] " << val << ", " << val2 << endl;
}
};

void GlobalFunc(int val, float val2)
{
cout << "[GlobalFunc] " << val << ", " << val2 << endl;
}

unsigned int WinSize(unsigned char *ColCnt,

unsigned char *RowCnt)
{
unsigned short result;
__asm {
mov ax, 1416h
int 10h
mov result, cx
les edi, ColCnt
mov es:[edi], bl //error illegal reference to 16-bit data in 'first operand’
les di, RowCnt
mov es:[edi], bh // the same problem
}
return(result);
}

int main()
{
// Create class instances
A a;
B b;
// Create an instance of the delegate
AddDelegate::Delegate del;
// Add our handlers
del += AddHandler(&a, &A::Fun1); // or del.Add(&a, A::Fun1);
del += AddHandler(&b, &B::Fun1); // or del.Add(&b, B::Fun2);
del += GlobalFunc; // or del.Add(GlobalFunc);
del += A::StaticFunc; // or del.Add(A::StaticFunc);
// Invoke the delegate
del(4, 5); // or del.Invoke(4, 5);
// Print the class values
cout << "[main] a.value = " << a.value << endl;
cout << "[main] b.value = " << b.value << endl;
// Remove some of the handlers
del -= AddHandler(&a, &A::Fun1); // or del.Remove(&a, A::Fun1);
del -= A::StaticFunc; // or del.Remove(A::StaticFunc);
// Invoke the delegate again
del(4, 5); // or del.Invoke(4, 5);
// Print the class values
cout << "[main] a.value = " << a.value << endl;
cout << "[main] b.value = " << b.value << endl;
return 0;
}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久6精品影院| 欧美在线视频观看免费网站| 伊人久久久久久久久久久| 欧美性猛交xxxx乱大交蜜桃| 国产啪精品视频| 97久久伊人激情网| 日韩精品视频在线播放| 欧美中文在线免费| 国产精品爱啪在线线免费观看| 国产精品aaaa| 国产午夜精品理论片a级探花| 精品一区二区三区三区| 日产日韩在线亚洲欧美| 中文字幕av一区二区三区谷原希美| xxx一区二区| 在线观看91久久久久久| 国产一区在线播放| 精品香蕉在线观看视频一| 亚洲欧洲日本专区| 亚洲综合中文字幕68页| 日韩欧美极品在线观看| 久久久欧美一区二区| 国产精品一区专区欧美日韩| 成人国产在线视频| 国产精品日韩电影| 国产欧洲精品视频| 国产精品免费视频久久久| 国产精品成人久久久久| 国产日韩精品综合网站| 久久99精品久久久久久青青91| 欧美一区二区三区精品电影| 欧美亚洲在线播放| 欧美美女15p| 国产精品综合久久久| 91久久精品久久国产性色也91| 久久人人爽亚洲精品天堂| 一区二区三区视频免费| 国产精品xxx视频| 国产精品美乳在线观看| 成人黄色片网站| 久久久999精品| 日韩成人在线播放| 亚洲aa中文字幕| 狠狠躁天天躁日日躁欧美| 亚洲美女黄色片| zzijzzij亚洲日本成熟少妇| 欧美一区二区视频97| 影音先锋欧美在线资源| 久久人91精品久久久久久不卡| 国产精品国内视频| 中文字幕国产亚洲| 亚洲jizzjizz日本少妇| 欧美精品在线视频观看| 久久免费视频在线| 久久久噜噜噜久久中文字免| 九色精品美女在线| 91日韩在线视频| 国产精品成人久久久久| 一区二区欧美激情| 欧美激情区在线播放| 欧美成人精品影院| 日韩二区三区在线| 国产第一区电影| 国产成人+综合亚洲+天堂| 欧美中文字幕视频| 久久99热这里只有精品国产| 亚洲自拍偷拍视频| 久久久噜噜噜久久久| 欧美综合激情网| 欧美激情第99页| 亚洲一区999| 国产精品91久久久| 欧美日在线观看| 亚洲精品视频在线观看视频| 亚洲成人网av| 色琪琪综合男人的天堂aⅴ视频| 亚洲国产精品视频在线观看| 久久久国产一区二区| 久久久视频精品| 国产精品∨欧美精品v日韩精品| 日韩欧美成人精品| 97在线视频一区| 播播国产欧美激情| 国产成人久久久精品一区| 日韩高清有码在线| 国产精品久久久久91| 久久91亚洲精品中文字幕奶水| 亚洲成人av在线播放| 久久久久久有精品国产| 日本久久精品视频| 综合激情国产一区| 精品免费在线视频| 九九热99久久久国产盗摄| 亚洲丝袜在线视频| 日韩在线观看免费全集电视剧网站| 91色琪琪电影亚洲精品久久| 九九视频这里只有精品| 国产精品女视频| 96精品久久久久中文字幕| 一区二区三区回区在观看免费视频| 日韩网站免费观看| 久久久久久久网站| 一区二区欧美在线| 亚洲视频网站在线观看| 亚洲精品国产精品国自产观看浪潮| 亚洲风情亚aⅴ在线发布| 狠狠综合久久av一区二区小说| 国产福利视频一区| 91sa在线看| 国产精品v日韩精品| 日韩在线观看网站| 一本一本久久a久久精品综合小说| 黄色精品在线看| 国产精品露脸av在线| 亚洲精品一区中文字幕乱码| 国产裸体写真av一区二区| 992tv成人免费影院| 国产精品久久一区主播| 91精品国产91久久久久福利| 性色av一区二区三区| 伊人久久综合97精品| 国产精品久久久久久久久久ktv| 亚洲女人天堂视频| 亚洲精品视频二区| 疯狂做受xxxx欧美肥白少妇| 中文字幕亚洲欧美在线| 精品福利在线观看| 亚洲片在线资源| 国产精品久久久久77777| 亚洲第一精品福利| 亚洲男人的天堂在线播放| 欧美大片网站在线观看| 亚洲白拍色综合图区| 91精品免费久久久久久久久| 国产亚洲免费的视频看| 2024亚洲男人天堂| 粉嫩av一区二区三区免费野| 亚洲精品国精品久久99热| 久热在线中文字幕色999舞| 日韩高清免费观看| 国产黑人绿帽在线第一区| 久久夜色精品亚洲噜噜国产mv| 成人福利网站在线观看| 91po在线观看91精品国产性色| 欧美中文在线观看| 欧美激情日韩图片| 亚洲第一av网| 国产精品扒开腿做爽爽爽的视频| 菠萝蜜影院一区二区免费| 欧美日韩亚洲激情| 97国产精品视频人人做人人爱| 国产综合在线看| 亚洲第一中文字幕在线观看| 成人a级免费视频| 精品亚洲aⅴ在线观看| 久久久精品一区二区三区| 亚洲欧洲午夜一线一品| 日韩av在线免费| 日韩在线观看视频免费| 亚洲欧美另类国产| 亚洲精品网址在线观看| 亚洲石原莉奈一区二区在线观看| 成人97在线观看视频| 91超碰中文字幕久久精品|