Конструкторы и деструкторы |
Автоматический вызов конструкторов предков не производится, т.е. вызов конструкторов базовых объектов необходимо выполнять явно.
Для создания интерфейса с вызовом нужного конструктора необходимо пользоваться оператором 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.