Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.03.09;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 год, там на компакте коллекция турбопаскалей, начиная с первого, заканчивая седьмым. Заодно и память освежишь.



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

Форум: "Основная";
Текущий архив: 2004.03.09;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.62 MB
Время: 0.009 c
3-25705
Belkova
2004-02-10 16:58
2004.03.09
Уважаемые мастера Delphi! Подскажите, как организовать цикл по вы


14-25914
Думкин
2004-02-15 07:11
2004.03.09
С днем рождения! 15 февраля.


1-25812
Grinder
2004-02-25 20:26
2004.03.09
StringList умная сортировка


1-25736
I_V_N_I_S_H
2004-02-26 23:59
2004.03.09
Перехват Print Scrn


1-25795
Mixa3
2004-02-27 09:09
2004.03.09
Как записать строку в record?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский