Конструкторы и деструкторы Назад В начало Вперед

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

Для создания интерфейса с вызовом нужного конструктора необходимо пользоваться оператором new:

<оператор-new> = new (<имя-интерфейса> [, <конструктор> ( <параметры> ) ] );

<имя-интерфейса> - имя создаваемого объекта.

<конструктор> - имя конструктора, вызываемого при создании.

<параметры> - параметры конструктора ( указываются при необходимости ).

Оператор new создаёт неразделяемый экземпляр объекта и возвращает ссылку на этот объект или NullRef, если загрузить объект не удалось.

При создании объектов другими способами (функции LoadVipInterface, LoadVipRef и т.д.) вызывается только конструктор по-умолчанию с фиксированным именем Init без параметров. Если такой конструктор не найден никакие другие конструкторы не вызываются.

  constructor Init;

Все конструкторы вызываются до вызова сообщений cmOnVipLoad и cmInit и перед инициализацией логической таблицы. Следовательно обращение к полям логических таблиц в конструкторах запрещено.

В отличие от событий cmInit (приходит перед открытием окна и не приходит при загрузке интерфейса по ссылке) и cmOnVipLoad (приходит при загрузке интерфейса по ссылке и не приходит при вызове RunInterface) конструктор вызывается всегда.

Примеры

Пример 1

//=============================================================
vipInterface iBase;
public:
  constructor Init; 		 // конструктор по умолчанию
  constructor InitName(aName : string); // доп. конструктор
  ...
end;

//=============================================================
vipInterface iUseful;
public:
  constructor Init; // перекрываем конструктор по умолчанию

  // iDataIfc - некий интерфейс с данными
  constructor InitData(aDataIfc : iDataIfc);
  ...
end;

//=============================================================
interface iBase;
  ...
//-------------------------------------------------------------
constructor Init;
{
  result := DoSomeTunes;
}

//-------------------------------------------------------------
constructor InitName(aName : string);
{
  result := false;

  if not iBase::Init then   // статический вызов
	exit;

  result := DoSetName(aName);
}
  ...
end.

//=============================================================
interface iUseful;
  ...
var myBase : iBase noauto;  // без автоинициализации

//-------------------------------------------------------------
constructor Init;
{
  result := false;

  if not inherited::Init then  // вызов конструктора предка
	exit;

  myBase := new(iBase); 	// вызовется Init

  if myBase = NullRef then
	exit;

  result := DoSomeUsefulTunes;
}

//-------------------------------------------------------------
constructor InitData(aDataIfc : iDataIfc);
{
  result := false;

  // вызов конструктора предка
  if not iBase::InitName(aDataIfc.Name) then
	exit;

  myBase := new(iBase, InitName (aDataIfc.Name));

  if myBase = NullRef then
	exit;

  result := DoSetData(aDataIfc);
}
  ...
end.

Деструктор вызывается после прохождения всех событий (cmDone, cmOnVipUnload) непосредственно перед разрушением объекта.

Пример 2

//=============================================================
vipInterface iBase;
public:
  ...
  destructor Done;
end;

//=============================================================
vipInterface iUseful;
public:
  ...
  destructor Done; // перекрываем реализацию
end;

//=============================================================
interface iBase;
  ...
//-------------------------------------------------------------
destructor Done;
{
  KillSomeObject; // уничтожить заведённые объекты
}
end.

//=============================================================
interface iUseful;
  ...
//-------------------------------------------------------------
destructor Done;
{
  CloseAllMyTables;  // закрыть все таблицы
  inherited::Done;   // вызвать деструктор предка
}
end.

Версия

Атлантис 5.0.