begin
p:=TDemo.Create; // Создание объекта
p.Master:=p; // Присвоение «умной ссылки»
… // Использование объекта
p.Free; // Уничтожение объекта
// При уничтожении «умная ссылка» p обращается в ноль: p=Nil!
end.
Листинг 7. Пример атомарного и защищенного метода класса.
function TDemo.Test:Integer; // Пример защищенной функции класса
begin
Result:=0; // Задаем значение по умолчанию
if Assigned(Self) then // Тест корректности ссылки объекта
try // Защищенная секция try … except …
Lock; // Блокировка объекта
Allocate; // Выделение нужных ресурсов
try // Защищенная секция try … finally …
… Work; … // Выполнение необходимых действий
Result:=…; // Окончательный результат вызова
finally // Секция освобождения ресурсов
Deallocate; // Освобождение ресурсов
Unlock; // Разблокировка объекта
end;
except // Секция обработки исключения:
on E:Exception do Report(E. Message); // Например, сообщение об ошибке
end;
end;
Листинг 8. Пример классов с использованием счетчиков и списков объектов.
unit Demo; // Модуль с описанием класса
interface uses Classes;
const
DemoCount:Integer=0; // Глобальный счетчик объектов класса
DemoList:TList=Nil; // Глобальный список объектов класса
type
TDemo = class(TObject) // Объявление класса
public // Открытые (публичные) поля:
constructor Create); // Создать объект
destructor Destroy; virtual; // Уничтожить объект
end;
implementation
constructor TDemo. Create; // Создать объект
begin
inherited Create;
InterlockedIncrement(DemoCount); // Поточно-безопасный инкремент счетчика
DemoList.Add(Self); // Регистрация объекта в списке
end;
destructor TDemo. Destroy; // Уничтожить объект
begin
DemoList.Delete(Self); // Удаление объекта из списка
InterlockedDecrement(FifoCount); // Поточно-безопасный декремент счетчика
inherited Destroy;
end;
initialization
DemoCount:=0; // Обнуляем счетчик при старте программы
DemoList:=TList.Create; // Создаем список при старте программы
finalization
if DemoCount<>0 // Если счетчик в конце ненулевой
then writeln(‘Утечка:’,DemoCount); // То пишем в журнал факт утечки ресурсов
end.
Program Demo; // Демонстрация использования списков
Uses Demo; var p:TDemo;
begin
p:=TDemo. Create; // Создаем объект
…
if DemoList.IndexOf(p)>=0 // Проверяем, существует ли такой объект
then … // и только тогда используем.
writeln(DemoCount); // Выводим счетчик числа объектов TDemo
…
end;
Листинг 9. Упрощенная реализация реестра объектов – иллюстрация принципа его работы.
program ObjectRegistryDemo; // Иллюстрация принципа реестра объектов
var reg : array[1..1024] of TObject; // Реестр объектов - массив указателей
stack : array[1..1024] of Integer; // Стек свободных индексных ссылок
sp : Integer; // Указатель стека индексных ссылок
obj : TObject; // Демонстрационный объект
ref,i : Integer; // Демонстрационная ссылка
procedure push(ref:Integer);
begin sp:=sp+1; stack[sp]:=ref; end; // Процедура кладет индекс в стек
function pop:Integer;
begin pop:=stack[sp]; sp:=sp-1; end; // Функция берет индекс из стека
type
TDemo=class(TObject) // Объект, регистрирующий себя в реестре
ref:Integer; // Индексная ссылка в реестре
constructor Create;
destructor Destroy; override;
end;
constructor TDemo. Create;
begin
inherited Create;
ref:=pop; // Берем из стека свободную ссылку
reg[ref]:=Self; // Кладем указатель объекта в реестр
end;
destructor Destroy;
begin
reg[ref]:=Nil; // Очищаем указатель в реестре
push(ref); // Возвращаем ссылку в стек
inherited Destroy;
end;
begin
sp:=0; while sp<1024 do push(sp+1); // Инициализация стека
obj:=TDemo. Create; // Создание объекта
ref:=obj. ref; // Запоминание ссылки объекта
...
if (ref>0) and (ref<=1024) then // Верификация индексной ссылки
if reg[ref] is TDemo then // Верификация указателя объекта
with reg[ref] as TDemo do... // Использование объекта по ссылке
...
reg[ref].Free; // Уничтожение объекта по ссылке
ref:=0; // Очистка ссылки
...
if sp<>1024 // Если в конце не все индексы в стеке
then writeln('Memory leak!'); // то есть утечка памяти-неубитые объекты
end.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |


