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

Пример 8.1.2. Свойства в Java.

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

// Java и J#

Import java.Io.*;

class CPlane // Класс, содержащий описание свойства

{

private int aSpeed; // Закрытая переменная свойства

public void setSpeed (int Sp) // Установить свойство

{ aSpeed= Sp;}

public int getSpeed () // Возвратить значение свойства

{ return aSpeed;}

}

public class Test

{

// static void Fm() {System.out.println(" Fm ()");} // Статическая ф-я

public static void main(String[] args)

{

CPlane sPlane= new CPlane ( ); // Создать объект

sPlane.setSpeed (600); // Присвоить значение свойства

System.out.println ((sPlane.getSpeed())); // Получить значение

//свойства и выдать на консоль

}

}

Как видим, в Java свойства – особый вид функций и, конечно, их нельзя применять в выражениях (не особый и применять их в выражениях можно - ОВН).

8.2Делегаты языков C++/CLI и C#

Делегат - это особый класс, объекты которого предназначены для хранения указателя функции, подлежащей выполнению. Являясь необычным объектом, объект делегата может объединять в себе с помощью операторов "+=" и "-=" несколько других объектов того же делегата, превратившись при этом в так называемый множественный объект делегат. Таким образом, объект делегата способен инкапсулировать указатели многих функций, но обязательно одного и того же формата. Инкапсулировав указатель функции, объект делегата делает его безопасным, поскольку как управляемый объект делегат контролируется системой. Делегат - это нововведение в .NET технологии и он специально введён, чтобы обезопасить программы от употребления опасных указателей.

Как любой объект, объект делегата создаётся из класса. Его класс наследует базовый класс Delegate библиотеки .NET Framework. Учитывая широкое использование делегатов в программах, разработчики .NET технологии существенно облегчили применение делегатов, поручив работу по созданию требуемого класса делегата не программисту, а компилятору. В последней версии языка C# ещё более упростилось создание объекта делегата и включение в него указателей функций.

Перед созданием объекта делегата необходимо описать тип (класс) делегата, но делается это необычно. Класс делегата генерирует компилятор, встретив ключевое слово delegate на языке C# или на языке C++/CLI.

Используя ключевое слово delegate, мы должны по определённому правилу определить формат функции, указатель которой инкапсулируется в этом делегате, и имя делегата. В дальнейшем имя этого делегата можно использовать для создания объектов делегата с аргументами его конструктора, задающими указатель конкретной функции. Параметры конструктора делегата несколько отличаются как для языков C# и C++/CLI, так и в зависимости от того, инкапсулируется ли в объекте делегата обычная или статическая функция класса.

Вызов объекта делегата приводит к выполнению инкапсулированной в нём функции. Если же к объекту делегата добавить с помощью оператора "+=" другие объекты делегата с инкапсулированными в них функциями, то при вызове этого множественного объекта делегата выполнятся функции всех добавленных объектов в том порядке, в котором они добавлялись. Перед вызовом объекта делегата необходимо убедиться, что он не пуст, то есть обладает инкапсулированной функцией; иначе возникнет системная ошибка.

Итак, располагая делегатом, мы выполняем функцию не прямо, а косвенно - через объект делегата. Мы вызываем объект делегата, и в круглых скобках задаём список необходимых аргументов. Все инкапсулированные в объекте делегата функции выполнятся с этими аргументами.

Мы можем передать объект делегата в любой объект, в котором требуется выполнить его функции. Можно передать объект делегата в качестве параметра функции. Более того, объект делегата, вызванный в одном объекте, может привести к выполнению функции другого объекта. На делегатах основаны так называемые события, передаваемые между объектами и приводящие к реакции этих объектов на события - выполнению так называемых обработчиков событий. По сути, событие является частным случаем делегата.

Итак, делегат - это средство делегирования функций. Объект делегата вызывается в одном месте, а делегированные им функции - там, где им надлежит выполняться "по приказу" (вызову) объекта делегата.

Постараемся понять суть и применение делегатов путём рассмотрения ряда примеров программ.

Перед использованием делегата необходимо объявить его тип:

// C#

delegate тип-возвр-значения имя-делегата (список-парам);

// C++/CLI

delegate тип-возвр-значения имя-делегата (список-парам);

где

delegate - ключевое слово делегата, указывающее компилятору о необходимости создания управляемого класса делегата с именем имя-делегата;

имя-делегата - это имя типа (или класса) делегата;

тип- возвр-значения - тип возвращаемого значения делегируемой функции;

список-парам - список типов параметров делегируемой функции.

Знающие язык C++.NET обнаружат, что разработчики языка C++/CLI решили в последней версии этого языка определить делегат так же как и в языке C#.

Объявление делегата тесно связано с форматом делегируемых им функций. Обратите внимание, что в объявлении делегата кроме его имени указаны только возвращаемое значение и список параметров функции. Такое объявление и реализация делегата предполагает делегирование функции любого имени, но точно с заданньши списком параметров и типом возвращаемого значения.

Более того, один объект делегата может быть использован для одновременного делегирования нескольких таких разноимённых функций, которые в нём могут накапливаться с помощью оператора "+=".

После объявления делегата перед его применением необходимо объявить ссылку или дескриптор на него, а затем с помощью оператора new или gcnew создать объект делегата описанного типа в управляемой куче и присвоить возвращённое им значение ранее объявленной ссылке или управляемому указателю (дескриптору).

Ссылка и дескриптор на объект делегата объявляются следующим образом:

// C#

имя-делегата ссылка-на-делегат;

// C++/CLI

имя-делегата ^дескриптор;

где

имя-делегата - это имя типа (или класса) делегата;

ссылка-на-делегат - имя ссылочной переменной на объект делегата;

дескриптор - имя управляемого указателя (дескриптора) на объект делегата.

Поскольку делегат является управляемым типом данных, то объект делегата создаётся в управляемой куче с помощью оператора gcnew на языке C++/CLI. Но создание объекта делегата применительно к обычной и статической функции класса отличается:

// C#

ссылка-на-делегат = new имя-делегата (ссылка-на-объект.имя-об-функции);

ссылка-на-делегат = new имя-делегата (имя-класса.имя-стат-функции);

// C++/CLI

дескриптор-делегата = gcnew имя-делегата (дескриптор-объекта.&имя-класса

::имя-об-функции);

дескриптор-делегата = gcnew имя-делегата (&имя-класса::имя-стат-функции);

где

имя-делегата - это имя типа (или класса) делегата;

ссылка-на-делегат - имя ссылочной переменной на объект делегата;

дескриптор-делегата - имя управляемого указателя на объект делегата;

ссылка-на-объект - имя ссылочной переменной на объект;

дескриптор-объекта – имя управляемого указателя на объект;

имя-класса - имя-класса, в котором описана функция;

имя-об-функции – имя обычной функции класса;

имя-стат-функции – имя статической функции класса.

Фирма Microsoft постоянно модифицирует свои программные продукты - операционные системы, среды разработки программ, компиляторы. Изменения коснулись не только языка C++.NET, но и языка C#. Теперь в языке C# создание объекта делегата упрощено и выглядит так

// C#

ссылка-на-делегат = ссылка-на-объект.имя-об-функции;// обычная функция

ссылка-на-делегат = имя-класса.имя-стат-функции; // статическая функция

Упростилось и добавление в объект делегата и удаление из объекта делегата указателей функций:

// C#

ссылка-на-делегат += {ссылка-на-объект.имя-об-функции | имя-класса.

имя-стат-функции};

ссылка-на-делегат -= {ссылка-на-объект.имя-об-функции| имя-класса.

имя-стат-функции};

Подробнее о нововведениях в языке C# рассмотрено в разделе 12. Пример 8.2.1 иллюстрирует создание и использование как одиночного, так и множественного объекта делегата.