Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.03.09;
Скачать: CL | DM;

Вниз

Конструкторы и статические методы.   Найти похожие ветки 

 
Макс Реалов   (2004-02-25 15:22) [0]

Я создаю класс и наследуюсь от класса, конструктор которого - статический метод (к примеру TRegistry или TObject).
(кстати, в справке Delphi написанно, что метод Create у TRegistry override, а компилятро говорит - static и в исходничках статический - хиловато сравочка у вас сделана ;)
Так вот,- когда отрабатывает статический конструктор класса-предка?
Пример:

TTest = class(TObject)
private
public
end;

TTest2 = class(TTest)
public
constructor Create; virtual;
end;
...
constructor TTest2.Create;
begin
cout << "TTest2 Create";
end;

Когда будет выполнен статический конструктор класса TTest?


 
Skier ©   (2004-02-25 15:28) [1]

>Макс Реалов (25.02.04 15:22)

> Когда будет выполнен статический конструктор класса TTest?

перед cout << "TTest2 Create";


 
Skier ©   (2004-02-25 15:28) [2]

а вообще зачем тебе это всё ?


 
Тимохов ©   (2004-02-25 15:33) [3]


> Макс Реалов (25.02.04 15:22)

В твоем примере никогда, т.к. ты его не вызываешь.


 
Skier ©   (2004-02-25 15:36) [4]

>Тимохов © (25.02.04 15:33) [3]
у TTest нет своего конструктора.


 
Тимохов ©   (2004-02-25 15:40) [5]


> Skier © (25.02.04 15:36) [4]
> >Тимохов © (25.02.04 15:33) [3]
> у TTest нет своего конструктора.

Это к чему?
Своего нет, но есть пришедший от TObject, который пустой.
Вопрос то был когда в примере автора выполнится конструктор, я ответил, никогда. Вроде я ничего такого неверного не сказал.


 
Макс Реалов   (2004-02-25 15:42) [6]

>> Skier © (25.02.04 15:28):

вот и я так подумал, но под отладчиком когда я такую ситуацию модулирую,- не получается зайти в процедуру создания родительского класса.
Зачем надо - долго объяснять.
...хотя, вот, пример придумал:
Надо инициализировать поля класса, порождённого от TObject, при его создании. Можно конечно в AfterConstruction это сделать, но зачем, если есть специальное место - конструктор? А Create у TObject не виртуальный, а мне этому классу надо конструктор виртуальный сделать. Вот я и беспокоюсь ;)
Хотя на самом деле просто интересно.

>> Тимохов © (25.02.04 15:33):
:))) ага, конечно. А как, по-твоему, все классы в Delphi реализованы? Они ведь ВСЕ от TObject"а порождены. А у него конструктор, извините, статический. Так что, батенька, не надо ля-ля. А если бы было так как ты говоришь - то грош цена всему вашему VCL"ю бы был :)


 
Макс Реалов   (2004-02-25 15:44) [7]

хотя может я чего в объектной структуре Delphi не догоняю :)


 
Тимохов ©   (2004-02-25 15:45) [8]


> Макс Реалов (25.02.04 15:42) [6]

Что-то я про "ля-ля" не понял.
Ты задал вопрос, я тебе ответил. Я не прав?
Судя по уровню твоих вопросов ты ответить прав ли я не можешь. Так что будем ждать опытных товарищей.

Судя по твоему комментарию skier"у ты немного не догоняешь работу с классами и объектами. При чем тут afterconstuction? Инициализируй поля в конструкторе и дело с концом. В чем вопрос то?


 
Skier ©   (2004-02-25 15:46) [9]

>Макс Реалов (25.02.04 15:42) [6]
Хм...а ты думаешь в Borland-e дураки сидят. :)
конструктор TObject специально сделан статическим чтобы
адрес конструктора базового класса был бы известен на этапе компиляции.


 
Тимохов ©   (2004-02-25 15:46) [10]

Зачем тебе виртуальный конструктор у TObject?


 
Тимохов ©   (2004-02-25 15:49) [11]


> Skier © (25.02.04 15:46) [9]

Вы это откуда взяли? Это домыслы или подтвержденная информация?


 
Макс Реалов   (2004-02-25 15:54) [12]

>> Skier © (25.02.04 15:46):
хех... разумно-разумно.
Ладно, сейчас в CPU гляну. Никуда не денется - всю правду покажет ;)

>> Тимохов © (25.02.04 15:45):
"При чем тут afterconstuction? Инициализируй поля в конструкторе и дело с концом. В чем вопрос то?"
См. Макс Реалов (25.02.04 15:42) [6].
либо я формулирую коряво, либо ты понимаешь коряво, либо одно из двух ;) Без обид, но твоё "Инициализируй поля в конструкторе " вынуждает меня ждать "опытных товарищей" :)


 
Тимохов ©   (2004-02-25 15:56) [13]


> Макс Реалов (25.02.04 15:54) [12]

Еще третье возможно - ты книжички по дельфи забыл почитать.


 
Макс Реалов   (2004-02-25 15:56) [14]

Тимохов © (25.02.04 15:49) [11]:
8))))))))))))))))
Respect for Delphi programmers 8))

All methods are static unless you specify otherwise when you declare them. Static methods work like regular procedures or functions. The compiler determines the exact address of the method and links the method at compile time.

Это ваш help. 8)


 
Тимохов ©   (2004-02-25 15:57) [15]


> Макс Реалов (25.02.04 15:42) [6]
> вот и я так подумал, но под отладчиком когда я такую ситуацию
> модулирую,- не получается зайти в процедуру создания родительского
> класса.

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

Ты что - сишник?


 
Тимохов ©   (2004-02-25 15:59) [16]


> Макс Реалов (25.02.04 15:56) [14]

Это то здесь причем?
Все верно написано.
Как это относится к тому, что Вы говорили раньше?
Что Вас смущает в жирной фразе?


 
Skier ©   (2004-02-25 15:59) [17]

TTest2 = class(TTest)
private
FField1 : Integer;
FField2 : String;
public
constructor Create; virtual;
end;
...
constructor TTest2.Create;
begin
FField1 := 123;
FField2 := "Hello, world !";
end;

И всё...


 
Макс Реалов   (2004-02-25 15:59) [18]

>>Тимохов © (25.02.04 15:56) [13]:

А что - по Delphi ещё и книжки есть? 8)

Ладно - флудить начали.
На самом деле Delphi - big respect! Просто когда на него резко пересаживают - тут уж не до книжек,- работу делать надо :|
А ООП я вообще не занимался до этого :/


 
KSergey ©   (2004-02-25 16:00) [19]

> [1] Skier © (25.02.04 15:28)
> > Когда будет выполнен статический конструктор класса TTest?
> перед cout << "TTest2 Create";

Чета я нифига не понимаю, товарисчи...
А разве без inherited в методе (в частности - в конструкторе) вызывается метод (конструктор) предка? Или это такое хитрое поведение именно конструкторов??
Я как-то всегда считал, что для статических методов вызывается тот метод, для которого класса я его вызываю - и все! Если там есть inherited - да, пожалуйста, вызовется и предка, а иначе - не вызовется. Разве это не так??


 
Тимохов ©   (2004-02-25 16:01) [20]


> Макс Реалов (25.02.04 15:59) [18]
> Ладно - флудить начали.

В общем-то согласен - почти флуд.
Если есть вопросы - задавай.


 
Skier ©   (2004-02-25 16:01) [21]

>Макс Реалов (25.02.04 15:54) [12]

> Ладно, сейчас в CPU гляну

Чтобы всё увидеть нужно будет включить галку Use Debug DCUs


 
Тимохов ©   (2004-02-25 16:01) [22]


> KSergey © (25.02.04 16:00) [19]

Все правильно вы понимаете.


 
Skier ©   (2004-02-25 16:03) [23]


> А разве без inherited в методе (в частности - в конструкторе)
> вызывается метод (конструктор) предка?

В данном случае вызовется конструктор TObject.


 
Макс Реалов   (2004-02-25 16:03) [24]

>> Skier © (25.02.04 15:59):
...ну да. Так я и сделал :)

>>Тимохов:

я не "сишник" - боже упаси :) про логическое программирование слыхал - вот из тех краёв :)

Всем спасиб.!


 
default ©   (2004-02-25 16:04) [25]

KSergey © (25.02.04 16:00) [19]
"Я как-то всегда считал, что для статических методов вызывается тот метод, для которого класса я его вызываю - и все!"
конечно так это, не воспринимай всерьёз
Макс Реалов (25.02.04 15:59) [18]
"А ООП я вообще не занимался до этого :/"


 
Тимохов ©   (2004-02-25 16:04) [26]


> Skier © (25.02.04 16:03) [23]

В каком данном случае?
В оригинальном вопросе вроде вообще вызова конструктора не было.


 
KSergey ©   (2004-02-25 16:05) [27]

> [6] Макс Реалов (25.02.04 15:42)

Я никак не пойму, что мешает проинициализировать поля в конструкторе? Религия? Других причин я не вижу ;) Вот и [17] Skier © (25.02.04 15:59)подсказывает. Только я не пойму какая при этом разница: виртуальный сей конструкторо или нет??

> [15] Тимохов © (25.02.04 15:57)
> Ты что - сишник?

Судя по вот этому - еще хуже: си плюс-плюсник ;)

> cout << "TTest2 Create ";


 
KSergey ©   (2004-02-25 16:11) [28]

> [23] Skier © (25.02.04 16:03)
> В данном случае вызовется конструктор TObject.

А это почему, интересно?
К стати, если уж придираться - то нифига пока не вызовается - нет кода создания объекта. Или я не прав?
Впрочем, может здесь имеется в виду то, что конструктор объекта TObject есть как бы по сути код создания самого объекта (включая выделение пемяти)- может в этом смысле конструктор TObject вызовется первым? Хотя что-то не уверен я в том... Вроде "конструктор объектов" вообщще - он, как я понимаю, как бы вне этой всей фигни... Хотя - как знать...


 
Skier ©   (2004-02-25 16:12) [29]


> Впрочем, может здесь имеется в виду то, что конструктор
> объекта TObject есть как бы по сути код создания самого
> объекта (включая выделение пемяти)- может в этом смысле
> конструктор TObject вызовется первым?

Именно так.


 
Тимохов ©   (2004-02-25 16:13) [30]


> KSergey © (25.02.04 16:11) [28]

Конструктор вообще мало чем отличается от обыкновенного метода.
Основное отличие это ключевое слова constructor, которое заставляет сделать вызов NewInstance, где и выделяется память.


 
Тимохов ©   (2004-02-25 16:18) [31]


> Skier © (25.02.04 16:12) [29]

Create сам не вызывается... :((((
Сам вызывается только newinstance


 
Skier ©   (2004-02-25 16:24) [32]

ты меня достал ! :)

вот что вызовется


function _ClassCreate(AClass: TClass; Alloc: Boolean): TObject;
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 //вот это и есть вызов newinstance.
@@noAlloc:
{$IFNDEF PC_MAPPED_EXCEPTIONS}
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
{$ENDIF}
POP EBX
POP ECX
POP EDX
RET

{$IFNDEF PC_MAPPED_EXCEPTIONS}
@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
{$ENDIF}
end;


 
Тимохов ©   (2004-02-25 16:28) [33]


> Skier © (25.02.04 16:24) [32]

Я помню, про Вас АП или panov (не помню точно) сказал, что вы обычно ведете себя корректно.

В данном случае вы меня тоже достали.
Вы мне не тыкайте кодом. Я его и так знаю.

Я возразил вашему высказыванию
---------------
> Впрочем, может здесь имеется в виду то, что конструктор
> объекта TObject есть как бы по сути код создания самого
> объекта (включая выделение пемяти)- может в этом смысле
> конструктор TObject вызовется первым?
Именно так.
---------------
Вы продолжаете утвержать "Именно так", на вопрос фразу "может в этом смысле конструктор TObject вызовется первым"?


 
Тимохов ©   (2004-02-25 16:31) [34]


> Skier © (25.02.04 16:24) [32]

И вообще про что речь?
В исходном вопросе нет вообще вызова конструктора.
Для плодотворного обсуждения надо понять из каких условий мы вообще исходим.

Я так понимаю, что весь сыр-бор из за вашего ответа 1. Вы продолжаете утвержать, что ответ 1 является правилным на вопрос "Когда будет выполнен статический конструктор класса TTest?"?


 
Skier ©   (2004-02-25 16:32) [35]

>Тимохов © (25.02.04 16:28) [33]
ты просто цепляешься к словам и продолжать в этом же духе у меня нет никакого желания...


 
Игорь Шевченко ©   (2004-02-25 16:34) [36]

Тимохов © (25.02.04 16:28)

Вы еще подеритесь, горячие финские парни. Посмотрите, во что компилируется ваш код, и будет вам счастье даром.


 
Тимохов ©   (2004-02-25 16:34) [37]


> Skier © (25.02.04 16:32) [35]

При всем моем большом уважении к вашему цвету, это второй раз когда я вас пытаюсь поправить на либо случайно, либо намеренно оброненную некорректную фразу.

Нет, я не цепляюсь к словам.
В данном случае есть некорректное высказываение.
Ваше дело признавать это или нет (в прошлый раз вы это не признали).


 
Тимохов ©   (2004-02-25 16:35) [38]


> Игорь Шевченко © (25.02.04 16:34) [36]

Я русский.

Повторю
"И вообще про что речь?
В исходном вопросе нет вообще вызова конструктора.
Для плодотворного обсуждения надо понять из каких условий мы вообще исходим."


 
Skier ©   (2004-02-25 16:36) [39]

>Тимохов © (25.02.04 16:34) [37]

> в прошлый раз вы это не признали

Про Dispose мне нечего было признавать.
Ибо неправ был именно ты.

А вообще ты забавен...:)


 
KSergey ©   (2004-02-25 16:43) [40]

> [32] Skier © (25.02.04 16:24)

А что, вызов NewInstance и конструктора TObject - это одно и тоже?? Ой ли?


 
Тимохов ©   (2004-02-25 16:44) [41]


> Skier © (25.02.04 16:36) [39]

О!!! Ты даже про dispose помнишь!!! Я горд собой, что я тебе запомнился.
Зачем ты говоришь, что я не прав.
Давай соглашение, ты выполняешь этот код, подтверждаешь свою неправоту (можешь в письме) и снова мир и спокойствие? :)))
type
t = rec
s: string;
end;
pt = ^t;
var
p1: pt;
p2: pointer;
i: integer
begin
showmessage(inttostr(allocmemsize));
for i := 0 to 100000 do
begin
new(p1);
p1^.s := stringofchar("0", 1000);
p2 := p1;
dispose(p2);
end;
showmessage(inttostr(allocmemsize));
end;


 
Тимохов ©   (2004-02-25 16:45) [42]


> KSergey © (25.02.04 16:43) [40]

Не давите на него, иначе он кучу асм кода даст :))))
Конечно, вещи разные.


 
Erik ©   (2004-02-25 16:47) [43]

Удалено модератором
Примечание: Ты не модератор


 
Skier ©   (2004-02-25 16:47) [44]

Я привёл код Borland-а к нему-то какие претензции ? :)


 
Тимохов ©   (2004-02-25 16:48) [45]


> Erik © (25.02.04 16:47) [43]

Может вы что-нить скажете, про разницу NewInstance и TObject.Create?
Вопрос то интересный, как оказалось, не все знают разницу :)))))


 
Skier ©   (2004-02-25 16:48) [46]


> Где модераторы, закройте эту бесполезную ветку.

Давно пора !


 
Тимохов ©   (2004-02-25 16:49) [47]


> Skier © (25.02.04 16:48) [46]

Я еще успел? :))))
Где признания!


 
Макс Реалов   (2004-02-25 16:53) [48]

>>Тимохов:
послушай умных дядь - посмотри CPU. Там всё хорошо видно, что как и когда вызывается. Если тебе очень влом могу разрадиться здесь asm-кодом :)

А по моему конкретному вопросу именно Skier аргументированно подтвердил мои догадки, а Шевченоко дал самый полезный совет :)


 
KSergey ©   (2004-02-25 16:55) [49]

> [43] Erik © (25.02.04 16:47)
> Где модераторы, закройте эту бесполезную ветку. Тут нет
> вопросов и разуммется ответов, один бесполезный флейм!

Ткните пальцем во флейм и отсутствие вопросов?? Пока лично я еще не на все вопросы ответы получил, а хотелось бы... Да, возможно от темы несколько уклонились - ну да там исходно вопрос странноватый ;)

> [44] Skier © (25.02.04 16:47)
> Я привёл код Borland-а к нему-то какие претензции ? :)

Совершенно никаких, лишь хочется получить ответ на вышеозвученный вопрос (спорить не буду, приму на веру ;) "Вызов NewInstance и конструктора TObject - суть вещт эквивалентные? Т.е. конструктор TObject есть NewInstance?"

PS
Вот только в случае утвердительного ответа останется для меня "небольшой" загадкой такой факт, правда не очень ориентируюсь и, боюсь, могу глупостей наговорить, ну да ладно ;) : в дельфи можно породить объект не от TObject, а просто класс (вроде говорят - это используется в KOL, точно синтаксис не помню). Тогда что же получится (если такое вообще возможно!): если это одно и тоже - NewInstance и конструктор TObject - то в случае наследования не от TObject не вызовется и NewInstance?? Т.е. память не выделится под экземпляр?? Но ведь такого не может быть, верно?


 
Тимохов ©   (2004-02-25 16:57) [50]


> Макс Реалов (25.02.04 16:53) [48]

Так в чем вопрос то - ты же ни где не вызывал конструктор.
Что смотреть то? :)))

Был странный вопрос, на него был получен странный ответ.
В чем спор... не пойму.

Ладно, зебъем.


 
Тимохов ©   (2004-02-25 16:59) [51]


> KSergey © (25.02.04 16:55) [49]

Выполениние самого тела конструктора мало чем отличается от выполнения любого иного метода.
Вопрос весь в ключевом слове constructor, которое заставляте сделать newinstance и потом вызвать тот конструктор, который вы указываете. Если в этом конструкторе не вызывать TObject.Create, то никто его сам не вызовет.


 
KSergey ©   (2004-02-25 17:02) [52]

> [51] Тимохов © (25.02.04 16:59)

Да ваша-то позиция мне ясна, во всяком случае я так же себе все это представляю.
Но мне было бы интересно услышать "голубеньких", уж извините за название ;)
Либо спор все же терминологический, и просто мы никак не можем о терминах договориться - а отсюда и прения...


 
DieHard   (2004-02-25 17:03) [53]

2KSergey:
TTest = class
эквивалентно
TTest = class(TObject)
если это имелось в виду...


 
Skier ©   (2004-02-25 17:04) [54]


> "Вызов NewInstance и конструктора TObject - суть вещт эквивалентные?
>

Нет.
В нашем примере будет вызван ещё TObject.InitInstance
А TObject.NewInstance лишь выделяет память Result := InitInstance(_GetMem(InstanceSize));


 
Erik ©   (2004-02-25 17:04) [55]

Поскольку тут форум а не отвлеченые дискусии на политические темы, то вопрос надо формулировать конкретно. Зачем это нужно, какую проблему мы хотим решить! А тут бала бала бала.....

To Тимохов
Тогда мене скажут по суть вопроса отвечать надо, а сути нет. Если говорить о хакеровском способе создания объекта, то конечно можно. Поскольку основное для объекта это выделение памяти. Но поменяют в чтото в следующей версии и будет крупный облом. Зачем так извращатся, что то придумывать непонимаю.


 
Тимохов ©   (2004-02-25 17:04) [56]


> KSergey © (25.02.04 17:02) [52]

Давайте успокоимся, мы представляем все правильно.


 
WebErr ©   (2004-02-25 17:09) [57]

Я тоже хочу пофлудить!
.......................................................
.......................................................
:)))))))))))))))))))))))))))))))))))))


 
Игорь Шевченко ©   (2004-02-25 17:18) [58]

unit main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TTest = class
public
constructor Create;
end;

TTest2 = class(TTest)
public
constructor Create; virtual;
end;

TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

{ TTest2 }

constructor TTest2.Create;
begin
ShowMessage("TTest2.Create");
end;

{ TTest }

constructor TTest.Create;
begin
ShowMessage("TTest.Create");
end;

procedure TForm1.Button1Click(Sender: TObject);
var
A : TTest;
begin
A := TTest2.Create;
try
ShowMessage(A.ClassName);
finally
A.Free;
end;
end;

end.


Компилируйте, смотрите в отладчике и все станет ясно.


 
mrcat ©   (2004-02-25 17:21) [59]

Игорь Шевченко © (25.02.04 17:18) [58]
единственно здравая мысль в ветке за последние постов этак 40 :)


 
Тимохов ©   (2004-02-25 17:28) [60]

Самая здравая мысль вообще за весь топик была в

Erik © (25.02.04 17:04) [55]
... суть вопроса отвечать надо, а сути нет ...

Нет вопроса, нет ответа.


 
KSergey ©   (2004-02-25 17:28) [61]

> [56] Тимохов © (25.02.04 17:04)
> > KSergey © (25.02.04 17:02) [52]
> Давайте успокоимся, мы представляем все правильно.

Блажен кто верует ;)

> [54] Skier © (25.02.04 17:04)
> > "Вызов NewInstance и конструктора TObject - суть вещт
> эквивалентные?
> Нет.
> В нашем примере будет вызван ещё TObject.InitInstance
> А TObject.NewInstance лишь выделяет память Result := InitInstance(_GetMem(InstanceSize));

Ага, понятнее. ;)
А тогда будьте добры, если не трудно, расставьте в порядке вызова слова:

TObject.NewInstance
TObject.InitInstance
TTest2.Create
TObject.Create

Я расставил так, как я себе это представляю, только для случая, когда внутри TTest2.Create есть inherited и код создания объекта выглядит как

TTest2.Create;

ЗЫ
но почему вы упорно привязываете NewInstance и InitInstance к TObject?? Это же самостоятельные процедуры, а не методы какого-либо класса??? Или я опять что-то недогоняю?

> [53] DieHard (25.02.04 17:03)
> 2KSergey:
> TTest = class
> эквивалентно
> TTest = class(TObject)
> если это имелось в виду...

Нет, не про это
Синтаксис, если не ошибаюсь, следующий:

TTest = object
...
end;


Во всяком случае такое компилируется, но это как бы "пустой" объект.. К стати, конструировать он себя похоже не умеет... Просто написание конструктора ни к чему не приводит - ошибка компиляции; может и правда NewInstance привязано к TObject?


 
Skier ©   (2004-02-25 17:29) [62]

TObject.Create это и есть TObject.NewInstance -> TObject.InitInstance


 
Игорь Шевченко ©   (2004-02-25 17:34) [63]

Skier © (25.02.04 17:29)

Усложняем задачу:

{ TTest2 }

constructor TTest2.Create;
begin
inherited;
ShowMessage("TTest2.Create");
end;

{ TTest }

constructor TTest.Create;
begin
inherited;
ShowMessage("TTest.Create");
end;



Компилируем, запускаем в отладчике, смотрим CPU Window.


 
KSergey ©   (2004-02-25 17:35) [64]

> [62] Skier © (25.02.04 17:29)
> TObject.Create это и есть TObject.NewInstance -> TObject.InitInstance

Извините, конечно, но вранье ;)
Я сейчас глянул в System и увидел следующее:

constructor TObject.Create;
begin
end;


Т.е. нифига там не вызывается ;)

Оним словом я понял так: проблема в терминах.
Дельфи-компилятор вызов конструктора любого объекта предваряет (автоматически!) вызовом TObject.NewInstance -> TObject.InitInstance. однако, мне кажется, это не еть "конструктор" TObject - собственно тот метод, что приписан конструктору TObject видим выше, он пуст.
Однако в моем понимании - именно это есть конструктор объекта (метод уже созданного экземпляра, вызываемый после создания этого экземпляра!), а не вызов NewInstance/InitInstance - это "заморочки" компилятора по созданию экземпляра объекта.

Ага?


 
Тимохов ©   (2004-02-25 17:36) [65]


> TObject.Create

нет - это не верно.


> KSergey © (25.02.04 17:28) [61]

Ваш порядок верный. Если в TTest2.Create не делать inherited, то TObject.Create вызван не будет. При этом объект корректно создасться с newinstance и initinstance. Все будет ок.


 
Игорь Шевченко ©   (2004-02-25 17:37) [66]


> Я сейчас глянул в System и увидел следующее:
>
> constructor TObject.Create;
> begin
> end;
>
> Т.е. нифига там не вызывается ;)


В CPU Window тоже поглядеть не мешает...


 
Тимохов ©   (2004-02-25 17:38) [67]


> KSergey © (25.02.04 17:35) [64]

Имхо вы сильно правы.
Я уже говорил выше о том, что create ничем не отличается от метода кроме constructor.


 
Skier ©   (2004-02-25 17:42) [68]

>KSergey © (25.02.04 17:35) [64]


> Дельфи-компилятор вызов конструктора любого объекта предваряет
> (автоматически!) вызовом TObject.NewInstance -> TObject.InitInstance.
>


Речь идёт об этой пустышке

стоит inherited или нет это пустышка ничего не делает,

constructor TObject.Create;
begin
end;

Разве нет ?

главную работу для TObject делают TObject.NewInstance -> TObject.InitInstance


 
Тимохов ©   (2004-02-25 17:47) [69]


> Skier © (25.02.04 17:42) [68]

Знаете, что-то сложно Вас понять.
Как Ваше текущее высказываение соотносится с

> Skier © (25.02.04 15:46) [9]
> >Макс Реалов (25.02.04 15:42) [6]
> Хм...а ты думаешь в Borland-e дураки сидят. :)
> конструктор TObject специально сделан статическим чтобы
> адрес конструктора базового класса был бы известен на этапе
> компиляции.


Т.е. с одной стороны в 68 вы правы, с другой стороны раньше вы имели в виду, что конструктор TObject.Create занимается выделением памяти и инициализацией? Как вас понимать? :))))))


 
Skier ©   (2004-02-25 17:53) [70]


> Как вас понимать?

А так и понимай - эта пустышка ничего не делает.
Borland сам подставит всё что нужно есть inherited или нет.


 
DieHard ©   (2004-02-25 17:54) [71]

2 KSergey:
As an alternative to class types, you can declare object types using the syntax

type objectTypeName = object (ancestorObjectType)

memberList
end;

where objectTypeName is any valid identifier, (ancestorObjectType) is optional, and memberList declares fields, methods, and properties. If (ancestorObjectType) is omitted, then the new type has no ancestor. Object types cannot have published members.
Since object types do not descend from TObject, they provide no built-in constructors, destructors, or other methods. You can create instances of an object type using the New procedure and destroy them with the Dispose procedure, or you can simply declare variables of an object type, just as you would with records.

Object types are supported for backward compatibility only. Their use is not recommended


 
Игорь Шевченко ©   (2004-02-25 17:55) [72]

Как работает конструктор любого объекта (в том числе и TObject):

Конструктор принимает два неявных аргумента в начале списка параметров VMT и CreateNew, то есть, выглядит соответственно:
constructor TTest2.Create (VMT : TClass; CreateNew : Boolean; .... остальные параметры)

В случае, если параметр CreateNew равен true (это происходит при внешнем вызове конструктора, таком как A := TTest2.Create), выполняется следующая последовательность действий:
call _ClassCreate // вызовы NewInstance, InitInstance
mov instvar, eax // instvar обычно регистр, в который
помещается адрес созданного экземпляра объекта, если тело конструктора не требует использования регистра eax, то этой строчки нету.

В случае внутреннего вызова конструктора CreateNew равен false и вышеприведенный код не выполняется.
После этого, в обоих случаях выполняется собственно тело конструктора, включая вызовы inherited конструкторов,
а после тела конструктора стоит еще одна проверка параметра CreateNew, если он равен True, вызывается виртуальный метод AfterConstruction.


 
Тимохов ©   (2004-02-25 17:58) [73]


> Skier © (25.02.04 17:53) [70]

Уважаемый, но вы же абсолютно правы. Я собственно это и пытаюсь вам сказать на протяжении 70 постов. Надо же, вы оказывается думаете так же :))))

Вот, что делает недопонимание между людьми :)))))
ЗЫ: Как там проверка про dispose? :))


 
Defunct ©   (2004-02-25 18:02) [74]

Игорь Шевченко © (25.02.04 17:34) [63]
Усложняем задачу еще сильнее:

Test = class(TObject)
...
Constructor Create;
Constructor CreateA;
Constructor SimSim;
Constructor DumDum;
Constructor Sozdavaisya;
Constructor CreateA1;Virtual;
Constructor CreateA2;Virtual;
Constructor CreateA3;Virtual;
Constructor CreateA4;Virtual;
End;

Test2 = class(Test)
Constructor CreatA1;Override;
End;


Если бы было так как говорит:

Skier © (25.02.04 16:12) [29]

> Впрочем, может здесь имеется в виду то, что конструктор
> объекта TObject есть как бы по сути код создания самого
> объекта (включая выделение пемяти)- может в этом смысле
> конструктор TObject вызовется первым?

Именно так.


То поидее при вызове перекрытого конструктора класса Test2 должны выполниться все статические конструкторы класса Test, а это само по себе полнейший абсурд.


 
Игорь Шевченко ©   (2004-02-25 18:05) [75]


> То поидее при вызове перекрытого конструктора класса Test2
> должны выполниться все статические конструкторы класса Test


Это зависит от тела перекрытого конструктора, что там будет выполняться.

К слову - а что, при вызове любого метода наследника выполняются абсолютно все статические методы предка ?


 
Defunct ©   (2004-02-25 18:06) [76]

Игорь Шевченко © (25.02.04 18:05) [75]
Так отож, я и говорю - абсурд полнейший


 
Тимохов ©   (2004-02-25 18:09) [77]

Не давите вы на skier! Здесь вопрос в терминологии. Он уже пояснил свою позицию - имхо она абс. верна.
Было недопонимание.


 
Skier ©   (2004-02-25 18:10) [78]

>Defunct © (25.02.04 18:06) [76]
Речь шла о конкретном примере и конкретно о TObject.Create
А довести до абсурда можно всё что угодно...


 
Тимохов ©   (2004-02-25 18:13) [79]

Если мне не изменяет память Create в ТрупоПаскале занамался именно выделением памяти. Для меня было большим удивлением в свое время узнать, что в дельфи сделали все по-другому.


 
Игорь Шевченко ©   (2004-02-25 18:25) [80]

Тимохов © (25.02.04 18:13)

Купи журнал "Мир ПК" №2 за 2004 год, там на компакте коллекция турбопаскалей, начиная с первого, заканчивая седьмым. Заодно и память освежишь.


 
Тимохов ©   (2004-02-25 18:27) [81]


>
> Игорь Шевченко © (25.02.04 18:25) [80]

Да меня 7ой дома стоит.
Вот только освежевывать память что-то не хочется.
Дельфи избаловал :))))


 
Макс Реалов   (2004-02-25 18:54) [82]

Мдя, явно проблема была по сути в терминологии.

Итак, подводим итог:
всегда вызывается код создания объекта заданного класса - см. Игорь Шевченко © (25.02.04 17:55) [72]. А конструктор ( constructor) для создаваемого объекта данного класса выполняется по inherited.

end.


 
Тимохов ©   (2004-02-25 18:58) [83]

С первым утверждением польностью согласен.
Со вторым не очень.

> А конструктор (constructor) для создаваемого объекта данного
> класса выполняется по inherited.

Я бы поправил, он выполняется не по inherited, а просто выполняется. А вот будут ли пыполненены конструкторы предков, это уже зависит от наличия inherited внутри тела конструктора данного класса.


 
Макс Реалов   (2004-02-25 19:07) [84]

>>Тимохов © (25.02.04 18:58) [83]:

ну естевственно :)
Сорьки, опечатался - конец рабочего дня, понимаешь :)


 
Тимохов ©   (2004-02-25 19:10) [85]

Наконец то
Достигнуто полнейшее понимание со всех сторон !!! :))))))

КОНЕЦ.


 
Гаврила   (2004-02-25 19:12) [86]

В общем, если все упростить
сигналом выделить память для компилятора является именно слово constructor а не то, что в его коде. Компилятором автоматически выделится память под все поля класса, кроме ссылочных.
Для ссылочных типов выделяется соответственно память под указатель (4 байта)



Страницы: 1 2 3 вся ветка

Текущий архив: 2004.03.09;
Скачать: CL | DM;

Наверх




Память: 0.72 MB
Время: 0.025 c
1-25773
DSP
2004-02-27 10:07
2004.03.09
список установленных программ


3-25713
pASkuda
2004-02-06 11:17
2004.03.09
Проблемы с передачей большого объема данных с сервера, на клиент.


8-25824
R2D2
2003-09-04 20:20
2004.03.09
Подскажите как наложить два изображения.


14-25916
SergP
2004-02-13 04:23
2004.03.09
Как лучше сделать запрос?


1-25768
sapsi
2004-02-26 10:48
2004.03.09
Минимизация формы