Конструктор - штука интересная. По сути это процедура, которая вызывается не ПРИ создании, а ДЛЯ создания объекта. Он имеет Параметр №0 и строчку №0. Параметр №0, это как в любом другом методе - Self, то есть ссылка на экземпляр класса, вызвавшего метод. Сточка №0 куда интереснее. Она проверяет Self на Nil. Если это так, то объект располагается в динамической памяти. В таком случае нужно ему её выделить, что конструктор и делает. Затем смотрит, имеет ли этот класс виртуальные методы. Если имеет, то заполняет его поле VMT (поле №0
) адресом VMT Этого класса. Затем уж происходит вызов того, что ты сам насочинял. Параметр Self к этому времени имеет уже корректное значение.
Мало того конструктор - единственная
функция, которая может быть вызвана без сохранения результатов при любой настройки компилятора. Да-да, именно функция. И та необычная. Её результат можно использовать как Boolean (для проверки вызова Fail в теле конструктора), как Pointer, чтобы узнать где расположился твой объект, и как указатель на экземпляр какого-то там класса.
Деструктор - штука более банальная. Он вызывается ПРИ уничтожении объекта и служит как правило для освобождения ресурсов занятых под нужды объекта. Например для класса списка, логично освобождать в нём память, а для файла - закрывать его.
Виртуальные функции - основа ООП. Вот тебе пример из ЛЮБОЙ книжки по паскалю, где вообще этот вопрос задевается:
Код
Uses Graph,CRT;
Type
TFigure=Object
x:Integer;
y:Integer;
Constructor Create(ax,ay:Integer);
Procedure Draw;Virtual;
Destructor Destroy;Virtual;
End;
TRound=Object(TFigure)
r:Integer;
Constructor Create(ax,ay,ar:Integer);
Procedure Draw;Virtual;
Destructor Destroy;Virtual;
End;
TRect=Object(TFigure)
a:Integer;
b:Integer;
Constructor Create(ax,ay,aa,ab:Integer);
Procedure Draw;Virtual;
Destructor Destroy;Virtual;
End;
Constructor TFigure.Create(ax,ay:Integer);
Begin
x:=ax;
y:=ay
End;
Procedure TFigure.Draw;
Begin
End;
Destructor TFigure.Destroy;
Begin
End;
Constructor TRound.Create(ax,ay,ar:Integer);
Begin
Inherited Create(ax,ay);
r:=ar
End;
Procedure TRound.Draw;
Begin
SetColor(Red);
Circle(x,y,r)
End;
Destructor TRound.Destroy;
Begin
SetColor(Black);
Circle(x,y,r)
End;
Constructor TRect.Create(ax,ay,aa,ab:Integer);
Begin
Inherited Create(ax,ay);
a:=aa;
b:=ab
End;
Procedure TRect.Draw;
Begin
SetColor(Red);
Rect(x,y,x+a,x+b)
End;
Destructor TRect.Destroy;
Begin
SetColor(Black);
Rect(x,y,x+a,x+b)
End;
Var
a:Array[0..99] Of ^TFigure;
i:Integer;
Begin
{InitGraph там какой-нибудь...}
For i:=Lo(a) To Hi(a) Do
If Random(2)=1 Then
a[i]:=New(TRound,Create(Random(GetMaxX),Random(GetMaxY),Random(100))
Else
a[i]:=New(TRect,Create(Random(GetMaxX),Random(GetMaxY),Random(100),Random(100));
For i:=Lo(a) To Hi(a) Do
a[i]^.Draw;
ReadKey;
For i:=Lo(a) To Hi(a) Do
Dispose(a[i],Destroy);
ReadKey;
RestoreCRTMode
End.
Уф... Запарился пока писал. Попробуй разберись сам - тут всё примитивно. Если что - спрашивай. Суть виртуальных примерно такая - они могут заменять или дополнять функции предков. В этом примере конструктор (он всегда типа виртуальный) дополняет метод предка, а процедура Draw - заменяет.
З. Ы. : а вообще,
Oleg_Z писал введение в ООП и закреплял его, по-моему. Там-то должно быть про это всё рассказано.