65.9K
CodeProject 正在变化。 阅读更多。
Home

托管C++中的委托

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.80/5 (4投票s)

2001 年 4 月 26 日

CPOL

2分钟阅读

viewsIcon

159065

downloadIcon

977

此示例演示使用 C++ 的单播和多播委托,包括声明、创建和使用,以及对类型安全的讨论。

引言

委托是 .NET 中与函数指针类型安全等效的。但委托更进一步。委托不仅可以指向并调用单个函数,.NET 中的委托还允许您拥有一个委托指向方法列表,每个方法将依次被调用。

创建单播委托

单播委托是指向单个方法的一个委托。要创建委托,您必须首先声明一个委托类型,该委托类型的签名与您希望调用的方法相同。例如,如果我们希望有一个委托调用一个以 String* 作为参数并返回 int 的函数,我们可以将其声明为

__delegate int MyDelegate(String *str);

单播委托是从 Delegate 隐式派生的。要使用委托来调用您的方法,您必须创建一个委托实例,并传入一个对象和您希望调用的该对象的方法。

例如,假设我们有一个托管类

__gc class MyClass 
{
public:
	int MethodA(String *str) 
	{
		Console::WriteLine(S"MyClass::MethodA - The value of str is: {0}", str);
		return str->Length;
	}
}

我们可以声明一个 MyClass 类型的对象和一个委托来调用对象的这些方法,如下所示

MyClass *pMC = new MyClass();
MyDelegate *pDelegate = new MyDelegate(pMC, &MyClass::MethodA);

使用委托调用对象的方法就像调用一样简单

pDelegate->Invoke("Invoking MethodA");

这将输出

MyClass::MethodA - The value of str is: Invoking MethodA

创建多播委托

多播委托允许您将方法链接在一起,以便在调用委托时依次调用每个方法。要创建多播方法,请使用静态 Delegate::Combine 方法将委托组合成一个多播委托。

在创建 beta 1 中的多播委托时,您必须使用 __delegate(multicast) 指令将您希望组合的委托声明为多播委托。这将创建一个从 MulticastDelegate 派生的委托。在 beta 2 中,您不使用 (multicast) 说明符,并且可以使用 Delegate::Combine 将您的单播委托组合成一个多播委托。

以下是一些示例代码,显示了两个多播委托被组合在一起(beta 2)

// Declare a delegate
__delegate int MyDelegate(String *str);

// Create a simple managed reference class
__gc class MyClass 
{
public:
    int MethodA(String *str) 
    {
        Console::WriteLine(S"MyClass::MethodA - The value of str is: {0}", str);
        return str->Length;
    }

    int MethodB(String* str) 
    {
        Console::WriteLine(S"MyClass::MethodB - The value of str is: {0}", str);
        return str->Length * 2;
    }
};

...

MyClass *pMC = new MyClass();
MyDelegate *pDelegate1 = new MyDelegate(pMC, &MyClass::MethodA);
MyDelegate *pDelegate2 = new MyDelegate(pMC, &MyClass::MethodB);

MyDelegate *pMultiDelegate = 
	static_cast<MyDelegate *>(Delegate::Combine(pDelegate, pDelegate2));

当您调用多播委托 pMultiDelegate 时,它将首先调用 MyClass::MethodA,然后调用 MyClass::MethodB。例如,调用

pMultiDelegate->Invoke("Invoking Multicast delegate");

将导致

MyClass::MethodA - The value of str is: Invoking multicast delegate
MyClass::MethodB - The value of str is: Invoking multicast delegate

类型安全

委托本质上是类型安全的。您无法使用错误的参数编译对委托的调用,也无法将委托的返回值分配给无法从委托所调用方法的返回类型隐式转换的类型。由于对象和方法被传递给委托构造函数,因此编译器拥有确保因参数和返回类型不匹配而导致的错误不会发生的所有信息。

© . All rights reserved.