Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Медведев_С++_CLI_C#_Java_J#.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
5.17 Mб
Скачать

Пример 8.2.1. Создание и использование делегата.

////////////////////

// C++/CLI

#include "stdafx.h"

using namespace System;

delegate void Del(String^); // Объявление делегата Del

ref class CA

{

public:

// Статическая функция класса

static void S1(String^ s){Console::WriteLine ("static S1: {0}", s);}

void R1(String^ s) { Console::WriteLine("usual R1:{0}", s);}

};

Void main() // Главная функция программы

{

CA ^pCA= gcnew CA(); // Создать объект pCA класса CA

Del ^pDel1= gcnew Del(&CA::S1); /* Создать объект pDell делегата Del

со статической функцией S1*/

pDel1("Статическая"); // Вызвать объект pDell делегата

Del ^pDel2= gcnew Del (pCA, &CA::R1); /* Создать объект pDel2 делегата

Del с обычной функцией R1*/

pDel2 ("Обычная"); // Вызвать объект pDel2 делегата

pDel2 += gcnew Del (&CA::S1); /* Добавить в объект pDel2 делегата

объект делегата со статической функцией S1*/

pDel2 ("Обычная и статическая"); /* Вызвать множественный объект

pDel2 делегата */

pDel2 -= pDel1; /* Удалить объект pDell делегата из

множественного объекта pDel2 делегата */

pDel2 ("После удаления"); // Вызвать объект pDel2 делегата

Console::ReadKey();

}

Результат:

static S1: Статическая

usual R1:Обычная

usual R1:Обычная и статическая

static S1: Обычная и статическая

///////////////////////////////

//C#

using System;

using System;

delegate void Del(string s); // Объявление делегата Del

class CA

{

// Статическая функция класса

public static void S1 (string s) {Console.WriteLine ("static S1: {0}", s);}

public void R1(string s) { Console.WriteLine("usual R1:{0}", s);}

}

class Program

{

static void Main(string[] args)

{

CA sCA = new CA(); // Создать объект sCA класса CA

Del sDell = new Del(CA.S1); /* Создать объект sDell делегата Del

со статической функцией S1*/

sDell ("Статическая"); // Вызвать объект sDell делегата Del

Del sDel2= new Del(sCA.R1); /* Создать объект sDel2 делегата Del

с обычной функцией R1*/

sDel2 ("Обычная"); // Вызвать объект sDel2 делегата Del

sDel2 += new Del (CA.S1); /* Добавить в объект sDel2 делегата

Del объект делегата Del со статической функцией S1*/

sDel2 ("Обычная и статическая"); /* Вызвать множественный объект

sDel2 делегата Del*/

sDel2 -= sDell; /* Удалить объект sDell делегата из множественного

объекта sDel2 делегата */

sDel2 ("После удаления"); // Вызвать объект делегата

Console.ReadKey();

}

}

Результат:

static S1: Статическая

usual R1:Обычная

usual R1:Обычная и статическая

static S1: Обычная и статическая

usual R1:После удаления

В программах примера 8.2.1 объявлен делегат Del, предписывающий возвращаемое значение void и только один параметр типа строки для всех делегируемых им функций. В классе CA описаны статическая S1() и обычная R1() функции, выдающие на консоль значение строкового apryмента s.

Функции Main() и main() создают объект класса CA, а затем объекты одиночного и множественного делегатов, вызывая их с разными строковыми аргументами. Одиночный объект делегата, ссылаемый с помощью ссылочной переменной sDel2 и дескриптора pDel2, после добавления к нему другого объекта делегата превращается во множественный объект делегата. Выполнение этого множественного объекта делегата вызывает выполнение двух функций включённых в него объектов делегата. Потом из множественного объекта делегата удаляется объект делегата - множественный объект делегата становится одиночным.

Обратите внимание, что поскольку делегат является управляемым данным, он может применяться только в управляемых классах. Поэтому в программе на языке C++/CLI перед описанием класса CA стоит ключевое слово ref, а объект делегата создаётся в управляемой куче с помощью оператора gcnew, и ссылка на него присваивается дескриптору (управляемому указателю).

Пример 8.2.2 интересен тем, что в нём показана передача указателя функции с помощью делегата в качестве параметра в другую функцию.