Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вопрос про метод Create


Демонов Е.В. ©   (2002-10-22 17:28:00) 

Часто на форуме виже следущее

TComeType=class(ParentType)
newVariable:....
constructor create(someParams);override;
end;

constructor TComeType.create(someParams);override;
begin
newVariable:=Значение;
OldVariable:=Значение;

inherited;
end;

Где OldVariable свойство или переменная класса ParentType.

Так вот разве это правельно - разве не нужно сначало вызвать
inherite а уж потом чегото инициализировать?


Юрий Зотов   (2002-10-23 11:15:00) [1]

Экземпляр класса теле самого конструктора НЕ создается. Он создается префиксным кодом, который генерит компилятор, если конструктор был вызван через ссылку на класс. Так что экземпляр класса создан как бы уже в "begin" и никакие inherited к этому отношения не имеют, хоть есть они, хоть их нет. Посмотрите, например, конструктор у TObject - он вообще пустой.

Аналогично - в деструкторе, сам деструктор ничего не уничтожает, это делает постфиксный код, который тоже генерит компилятор.


han_malign   (2002-10-23 11:04:00) [2]

procedure _ClassCreate;
asm
{ -> EAX = pointer to VMT }
{ <- EAX = pointer to instance }
PUSH EDX
PUSH ECX
PUSH EBX
TEST DL,DL
JL @@noAlloc
CALL dword ptr [EAX]. vmtNewInstance
@@noAlloc:
XOR EDX,EDX
LEA ECX,[ESP+16]
MOV EBX,FS:[EDX]
MOV [ECX].TExcFrame.next,EBX
MOV [ECX].TExcFrame.hEBP,EBP
MOV [ECX].TExcFrame.desc,offset @desc
MOV [ECX].TexcFrame.ConstructedObject,EAX { trick: remember copy to instance }
MOV FS:[EDX],ECX
POP EBX
POP ECX
POP EDX
RET

@desc:
JMP _HandleAnyException

{ destroy the object }

MOV EAX,[ESP+8+9*4]
MOV EAX,[EAX].TExcFrame.ConstructedObject
TEST EAX,EAX
JE @@skip
MOV ECX,[EAX]
MOV DL,$81
PUSH EAX
CALL dword ptr [ECX].vmtDestroy
POP EAX
CALL _ClassDestroy
@@skip:
{ reraise the exception }
CALL _RaiseAgain
end;


procedure _ClassDestroy;
asm
MOV EDX,[EAX]
CALL dword ptr [EDX]. vmtFreeInstance
end;


Демонов Е.В.   (2002-10-23 11:00:00) [3]

Нет.. Я просто думал что inherited в конструкторе собственно кроме действий перекытого метода Create вызавет там какието (не помню так сразу чтото на initInstance похожее-?) методы которые собственно и создадут экземпляр класса. Поэтому я не понимаю как до создания экземепляра класса словом inherited в методе Create можно инициалицировать какието ни было поля и свойства ?

Или собственно дело в том что create обознаxен как Constructor- и значит при его вызове сразу создаётся экземпляр, а inherited только вызывает унаследованный метод ?

Также и с Destructordestroy ?


han_malign   (2002-10-23 11:00:00) [4]

Извиняюсь не Classes.pas а System.pas


han_malign   (2002-10-23 10:59:00) [5]

2 Bis
В Delphi поля объекта обнуляются в InitInstance, который вызывается перед входом в первый конструктор независимо от наличия inherited. (см. Classes.pas {compiller magic} _ClassCreate->NewInstance->InitInstance)


Bis   (2002-10-23 10:45:00) [6]

но лучше все таки писать, тем более он "обнуляет" все переменные объекта, а это помогает в случае "забывчивости" избежать многих ошибок


han_malign   (2002-10-23 10:43:00) [7]

Не почему, а зачем - при наследованиеи объектов, главная цель изменить(не всегда - расширить) функциональность, а каким образом - зависит от разработчика


Демонов Е.В.   (2002-10-23 10:39:00) [8]

>>Юрий Зотов
Почему ?


Юрий Зотов   (2002-10-22 18:20:00) [9]

Inherited можно писать в любом месте, где Вам требуется, и даже не писать совсем, если это не требуется.


han_malign   (2002-10-22 17:55:00) [10]

Писать inherited Create - первым, а inherited Destroy - последним - считается правилом хорошего тона. Очень редко, когда полностью известна реализация предка, могут понадобится танцы с бубном(например чтобы изменить поведение унаследованного конструктора) - но обычно это говорит о неграмотном проектировании иерархии объектов.

type
TChild = class(TParent)
.........
end;
type TMyObjectClass = class of TMyObject;
const FMyObjectClass: TMyObjectClass = TMyObject;

constructor TParent.Create;
begin
FMyObject:=FMyObjectClass.Create;
end;

constructor TChild.Create;
begin
FMyObjectClass:=TMyObject1;
inherited;
end;


alxx   (2002-10-22 17:47:00) [11]

Похоже, что это неправильно.


Наверх

Титульная страница Поиск, карта сайта Написать письмо