Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Создание и уничтожение объектов






Object Pascal использует так называемую ссылочную объектную модель[3]. Это означает, что все объекты размещаются в памяти динамически, а объектные переменные фактически являются указателями на данные объекта в динамической памяти и имеют одинаковый размер (4 байта). Однако для доступа к данным объекта не используется символ разыменовывания ^ (записывается Man.fName, а не Man^.fName, хотя подразумевается именно второе). Для начального размещения объектов в динамической памяти служит особый вид методов, называемых конструкторами.

Чтобы объявить метод как конструктор, используется ключевое слово constructor. Оно записывается вместо слова procedure при определении метода в классе и при реализации метода (конструктор не может быть функцией). Компилятор автоматически добавляет к телу конструктора код, выделяющий в динамической памяти участок для полей объекта и обнуляющий этот участок. Так как конструктор необходимо выполнить перед использованием объекта, то в тело конструктора обычно помещают операторы инициализации объекта, например, задание начальных значений для полей. Отметим, что Object Pascal допускает существование в классе нескольких конструкторов. Традиционное имя для конструктора – Create.

Добавим конструктор в класс TPerson:

type TPerson = class

...

constructor Create;

end;

 

constructor TPerson.Create;

begin

fAge: = 1;

fName: = 'Person'

end;

Синтаксис вызова конструктора: имя-объекта: = имя-класса.имя-конструктора:

Man: = TPerson.Create;

Конструктор можно вызывать в виде имя-объекта.имя-конструктора, т. е. как обычный метод:

Man.Create;

Такой вызов означает простое выполнение тела конструктора (ре-инициализацию полей). Его можно применять только для тех объектов, которые уже размещены в памяти.

Если объект не используется, то занимаемая им динамическая память должна быть освобождена. Для уничтожения объектов предназначены особые методы – деструкторы.

Для объявления деструкторов используется ключевое слово destructor. Тело деструктора – подходящее место для финальных действий с объектом. Традиционное имя для деструктора – Destroy.

Добавим в класс TPerson деструктор:

type TPerson = class

...

constructor Create;

destructor Destroy;

end;

 

destructor TPerson.Destroy;

begin

fAge: = 0;

fName: = ''

end;

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

Man: = TPerson.Create; // создание объекта

Man.fName: = 'John Dow'; // работа с объектом

Man.Destroy; // уничтожение объекта

Деструктор можно вызвать только у инициализированного объекта. Попытка вызвать деструктор у неинициализированного объекта может привести к исключительной ситуации в работе программы.

В качестве примера работы с конструкторами и деструкторами рассмотрим класс для представления структуры данных бинарное дерево целых чисел. Такое дерево хранит в каждом узле некий целочисленный вес, а так же ссылки (возможно пустые) на правое и левое поддерево. Реализуем в классе единственный метод для подсчёта веса всего дерева.

type TBTree = class

Weight: Integer;

Left, Right: TBTree;

function GetWeight: Integer;

end;

 

function TBTree.GetWeight;

begin

Result: = Weight;

if Left < > nil then inc(Result, Left.GetWeight);

if Right < > nil then inc(Result, Right.GetWeight);

end;

Снабдим класс TBTree двумя конструкторами. Первый будет устанавливать вес узла, второй кроме этого будет инициализировать левое и правое поддеревья. Хотя эти два конструктора можно назвать по-разному, дадим им одинаковые имена и воспользуемся возможностью перегрузки подпрограмм:

type

TBTree = class

...

constructor Create(W: Integer); overload;

constructor Create(W: Integer; LTree, RTree: TBTree); overload;

end;

 

constructor TBTree.Create(W: Integer);

begin

Weight: = W;

end;

 

constructor TBTree.Create(W: Integer; LTree, RTree: TBTree);

begin

Weight: = W;

Left: = LTree;

Right: = RTree;

end;

Работа с классом TBTree может выглядеть так:

var T: TBTree;

...

T: = TBTree.Create(10);

T.Left: = TBTree.Create(20);

T.Right: = TBTree.Create(100, TBTree.Create(400), TBTree.Create(5));

Y: = T.GetWeight; // 10 + 20 + 100 + 400 + 5

Добавим в класс TBTree деструктор. Одно из правил ООП гласит: «Если объект во время работы самостоятельно резервировал динамическую память, она должна быть освобождена деструктором класса». Деструктор для класса TBTree будет выглядеть следующим образом:

type TBTree = class

...

destructor Destroy;

end;

 

destructor TBTree.Destroy;

begin

if Left < > nil then Left.Destroy;

if Right < > nil then Right.Destroy;

end;

Приведём полный пример консольного приложения с классом TBTree:

program BinaryTree;

 

{$APPTYPE CONSOLE}

 

type

TBTree = class

Weight: Integer;

Left, Right: TBTree;

constructor Create(W: Integer); overload;

constructor Create(W: Integer; LTree, RTree: TBTree); overload;

function GetWeight: Integer;

destructor Destroy;

end;

 

constructor TBTree.Create(W: Integer);

begin

Weight: = W;

end;

 

constructor TBTree.Create(W: Integer; LTree, RTree: TBTree);

begin

Weight: = W;

Left: = LTree;

Right: = RTree;

end;

 

function TBTree.GetWeight;

begin

Result: = Weight;

if Left < > nil then inc(Result, Left.GetWeight);

if Right < > nil then inc(Result, Right.GetWeight);

end;

 

destructor TBTree.Destroy;

begin

if Left < > nil then Left.Destroy;

if Right < > nil then Right.Destroy;

end;

 

var T: TBTree;

 

begin

T: = TBTree.Create(10);

T.Left: = TBTree.Create(20);

T.Right: =

TBTree.Create(100, TBTree.Create(1000), TBTree.Create(5));

writeln(T.GetWeight);

T.Destroy;

end.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.