Ада-95. Компилятор GNAT


Динамическая диспетчеризация


При внимательном рассмотрении показанной ранее реализации процедуры Show

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

В данном случае, подразумевается, что если мы решим описать новый тип, производный от любого типа входящего в показанную иерархию (Root, Child_1, Child_2 и Grand_Child_2_1), то результатом работы такой реализации процедуры Show

всегда будет сообщение "Unknown type", извещающее о том, что фактический тип параметра Self - не известен.

Например, такая ситуация может возникнуть когда мы опишем новый тип Grand_Child_1_1, производный от типа Child_1, в каком-либо другом пакете.

С первого взгляда может показаться, что будет достаточно переписать процедуру Show

с учетом нового типа Grand_Child_1_1.

Действительно, такое решение будет работать, но это значит, что при описании каждого нового типа, входящего в эту иерархию, мы вынуждены вносить изменения в уже написанные и отлаженные модули.

Для того, чтобы избавиться от таких трудностей, реализацию процедуры Show

надо действительно переписать, но так, чтобы задействовать механизм динамической диспетчеризации вызовов подпрограмм, который предоставляет использование тэговых типов.

Вспомним, что при демонстрации примера иерархии типов, был также приведен пример спецификации пакета Simple_Objects, в котором эта иерархия типов описывается.

Теперь, перед непосредственным обсуждением механизма динамической диспетчеризации вызовов подпрограмм, предположим, что описание тела этого пакета имеет следующий вид:

with Ada.Text_IO;

package body Simple_Objects is

-- примитивные операции типа Root

function The_Name (Self: in Root) return String is

begin

return ("Root"); end The_Name;

procedure Show (Self: in Root'Class) is

begin

Ada.Text_IO.Put_Line ( The_Name(Self) ); end Show;

-- примитивные операции типа Child_1

function The_Name (Self: in Child_1) return String is

begin

return ("Child_1"); end The_Name;

-- примитивные операции типа Child_2

function The_Name (Self: in Child_2) return String is

begin

return ("Child_2"); end The_Name;

-- примитивные операции типа Grand_Child_2_1

function The_Name (Self: in Grand_Child_2_1) return String is

begin

return ("Grand_Child_2_1"); end The_Name;

end Simple_Objects;

<


- Начало -  - Назад -  - Вперед -



Книжный магазин