Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл: Источник:
Скачиваний:
100
Добавлен:
04.03.2014
Размер:
235.01 Кб
Скачать

Var p:pTObj;

Begin New(p,Init(5));

p^.Print;

Dispose(p,Done);

End.

При работе с динамическими объектами желательно выполнять контроль распределения памяти из кучи. Отсутствие такого контроля может при недостатке памяти привести к ошибке распределения памяти и нарушению работы ЭВМ.

Организация перехвата управления при выполнении контроля требует замены встроенной функции управления обработкой ошибок распределения памяти из кучи (см. Help). Замена выполняется таким образом, что при отсутствии необходимого количества памяти процедура или функцияNewвозвращаетnilвместо адреса. Если памяти не хватает для размещения динамических полей, то, мы получимnilвместо адреса поля. В конструкторе в этом случае можно указать специальную директивуfail, выполнение которой приводит к тому, что распределение памяти под объект и предыдущие динамические поля аннулируется, и указатель на объект становится равнымnil.

Пример 9. Динамический объект с динамическим полем и контролем выделяемой памяти.

Program ex;

Type pTObj=^TObj;

TObj=Object

pPole:^real;

procedure Print;

constructor Init(p:real);

destructor Done;

end;

Procedure TObj.Print;

Begin WriteLn('Значение поля = ',pPole^); end;

Constructor TObj.Init(p:real);

Begin New(pPole); {выделение памяти под дин. поле}

if pPole=nil then {если не хватает памяти}

begin Done; {то выполнить деструктор}

fail; {и аннулировать распределение памяти}

end;

pPole^:=p; {иначе - занести информацию в поле}

end;

Destructor TObj.Done;

Begin if pPole<>nil then {если память распределена,}

Dispose(pPole); {то освободить память}

end;

{процедура управления обработкой ошибок при выделении памяти}

{$F+}

Function HeapFunc(size:Word):integer;

Begin HeapFunc:=1; end;

{$F-}

Var p:pTObj;

Begin HeapError:=@HeapFunc; {замена процедуры}

New(p,Init(5));

if p=nil then {если не хватает памяти}

begin WriteLn('Не хватает памяти в куче.');

Halt(2);

end;

p^.Print;

Dispose(p,Done);

End.

Поскольку для статических объектов отсутствует возможность проверки правильности распределения памяти под динамические поля через проверку значения указателя на объект, как для динамических объектов, для них в этом случае используется проверка возвращаемого значения конструктора, который в этом случае вызывается как функция типа boolean. Если возвращаемое значение равноfalse, то в конструкторе была выполнена директиваfail.

Пример 10. Статический объект с динамическим полем и контролем распределения памяти в куче.

Program ex;

Type TObj=Object

pPole:^real;

procedure Print;

constructor Init(p:real);

destructor Done;

end;

Procedure TObj.Print;

Begin WriteLn('Значение поля = ',pPole^); end;

Constructor TObj.Init(p:real);

Begin New(pPole);

if pPole=nil then

begin Done;fail;end;

pPole^:=p;

end;

Destructor TObj.Done;

Begin if pPole<>nil then Dispose(pPole); end;

{$F+}

Function HeapFunc(size:Word):integer;

Begin HeapFunc:=1; end;

{$F-}

Соседние файлы в папке Методичка С++