Текущий архив: 2009.11.15;
Скачать: CL | DM;
Вниз
object`ы в delphi 2009 Найти похожие ветки
← →
sniknik © (2008-10-16 13:38) [40]> абсолютно также как с классом, тотже vmt, все честно, никакого мошенства))
ну да, конечно...
виртуальные методы определяются на этапе создания конструктором. где создание статического объекта? что у него делает "конструктор", если он не "конструирует"?
← →
Сергей М. © (2008-10-16 13:42) [41]
> лучше 1 раз память выделю
где, в какой секции ?
← →
просто так (2008-10-16 13:53) [42]>>sniknik
конструктор вписывает адрес vmt в указатель на vmt расположенный в области памяти полей.
>>Сергей М.
выделю 1 раз память под массив в куче.
← →
Сергей М. © (2008-10-16 13:58) [43]
> выделю 1 раз память под массив в куче
Так тебе ж все равно бежать потом в цикле по этому массиву для конструирования каждого элемента !
← →
Anatoly Podgoretsky © (2008-10-16 14:05) [44]> просто так (16.10.2008 13:53:42) [42]
Опять же смотрим справку
they provide no built-in constructors, destructors, or other methods
← →
Anatoly Podgoretsky © (2008-10-16 14:11) [45]> Сергей М. (16.10.2008 13:58:43) [43]
И это будут не статические, а динамические объекты
← →
Сергей М. © (2008-10-16 14:40) [46]
> Anatoly Podgoretsky © (16.10.08 14:11) [45]
Да хоть бы и статические.
Сути не меняет - все равно конструирование в том или ином виде требуется, иначе нафих вообще вся эта бодяга с объектами..
← →
Сергей М. © (2008-10-16 14:49) [47]К тому же нафих тут массив объектов ?
Точка она и в африке точка, для ее описания достаточно обычной структуры.
Каким поведением отличаются точки, если их рассматривать как объекты - не понятно ..
← →
sniknik © (2008-10-16 15:00) [48]> конструктор вписывает адрес vmt в указатель на vmt расположенный в области памяти полей.
может он и вписывает, просто как переменную (адрес), но вызовы идут как статические. проверь// a.initxywh;
a.crash;
ShowMessage(IntToStr(integer(a.test)));
и вместо
test:=nil;
записать туда чтото, чтобы было видно
test:= Pointer(-1);
на d7 это работает, что показывает метод crash не виртуальный, вызов как статического/классового.
у тебя это должно дать ошибку, если 2009 "честный".
и кстати, раз ты уж про память объектов заговорил, посмотри на sizeof(zbasic), при стоящим virtual у процедуры, а после убери, и посмотри еще раз. вот тебе те 4 байта которые ты "экономил" на указателе отказавшись от динамических классов. а если ещё такая процедура не одна...
← →
Sapersky (2008-10-16 15:55) [49]может он и вписывает, просто как переменную (адрес), но вызовы идут как статические.
Вызовы "изнутри" объекта динамические. Т.е. если в объекте-родителе есть вызов виртуальной функции, которая замещена в наследнике, вызовется именно функция наследника.
Хотя и не полноценный полиморфизм, но иногда может быть полезно.
а если ещё такая процедура не одна...
Одна или не одна - неважно, VMT не цепляется полностью к каждому объекту, просто добавляется указатель на неё.
Хотя да, экономия по сравнению с TPoint + TList получается сомнительная, преимущество разве в том, что данные лежат "одним куском". И то этот кусок нельзя, допустим, "одним махом" читать/писать из файла, чтобы не испортить указатели на VMT. В общем, структура данных на любителя...
Ещё тов. "просто так" следует иметь в виду, что объекты не вполне совместимы с compiler magic типами вроде LongString (независимо от версии Дельфи). Впрочем, это вполне соответствует статусу "for backward compatibility only", в старом коде никаких LongString нет.
← →
просто так (2008-10-16 16:53) [50]>>Каким поведением отличаются точки, если их рассматривать как объекты - не понятно ..
точки к примеру. подойдет любая структура маленкого размера. в моем случае точка
>>И это будут не статические, а динамические объекты
Я не програмист, и наверно тебя не понимаю, но объект можно создать и статически и динамически в отличае от класса
>>Сути не меняет - все равно конструирование в том или ином виде требуется, иначе нафих вообще вся эта бодяга с объектами..
требуется только при наличии виртуальных методов, без них конструктор в принципе можно не вызывать
>>может он и вписывает, просто как переменную (адрес), но вызовы идут как статические. проверь
в данном примере вызовы оптимизируются до статических, пример только чтоб показать ошибку
>>вот тебе те 4 байта которые ты "экономил" на указателе отказавшись от динамических классов. а если ещё такая процедура не одна...
эти 4 байта присутствуют и в классе, даже больше. я говорил про экономию от массива объектов над массивом указателей на объект
>>И то этот кусок нельзя, допустим, "одним махом" читать/писать из файла, чтобы не испортить указатели на VMT. В общем, структура данных на любителя
Писать одним махом в принципе можно, если забить на выравнивания и при чтении прогонять для всех пустой конструктор. но это да, на любителя
>>Ещё тов. "просто так" следует иметь в виду, что объекты не вполне совместимы с compiler magic типами вроде LongString
вышеуказаный товарисч в курсе)) это не смертельно
← →
DevilDevil © (2008-10-16 16:58) [51]> просто так (16.10.08 13:53) [42]
не трать своего драгоценного времени - они не поймут.
Должна быть OOП-структура с виртуальными методами. + должны быть директивы автоконсруктора/автодеструктора. Это моё мнение.
← →
DevilDevil © (2008-10-16 16:59) [52]будем надеяться, что object вернут... или хотя бы доделают record
← →
просто так (2008-10-16 17:42) [53]а смысл доделывать рекорд? чтоб получить обжект который нафиг никому не нужен((?
ох уж этот маркетинг
← →
sniknik © (2008-10-16 18:03) [54]> Хотя и не полноценный полиморфизм, но иногда может быть полезно.
возможно.
> Одна или не одна - неважно, VMT не цепляется полностью к каждому объекту, просто добавляется указатель на неё.
--->
> посмотри на sizeof(zbasic)
с классами, и "настоящим" vmt согласен на все 100%, но здесь какое то жалкое подобие...
я не зря по sizeof сказал, в примере, с того с которого начинается ветка у меня (D7) sizeof показывает 8 байт (4 под переменную, 4 под "виртуальный" метод), и при том что "виртуальный" метод не инициализирован (nil вмеcто адреса) вызов его нормально работает, как показывал. и что это значит? то что данные в структуре/"vmt" тут при вызове не используются.
а стоит снять "виртуальность" они и из структуры пропадают (4 байта становиться).
и то что эти байты не цепляются ко всем объектам это ты не подумав сказал... объекты статические!
делаешь такvar
a, b, c: zbasic;
mas: array[0..SizeOf(zbasic)*3] of byte absolute a;
begin
a.initxywh;
b.initxywh;
c.initxywh;
end.
смотри на массив mas при
procedure crash; virtual;
и
test:= Pointer(-1);
очевидно заполнение, и можешь посчитать байты если мне не доверяешь.
после убирай
procedure crash; //virtual;
и смотри снова. к каждому объекту цепляется или нет.
← →
Сергей М. © (2008-10-16 18:11) [55]
> просто так (16.10.08 16:53) [50]
> точки к примеру
Хорошо.
Создай тем же макаром массив полиморфных объектов ..
← →
просто так (2008-10-16 18:29) [56]>>Сергей М.
Я про фому, ты про ерему, тут мне ненужно 50000 разных объектов, нужно 50000 точек. без выделений памяти под каждый объект отдельно. я прекрасно понимаю что под разные объекты в обном массиве без указателей не обойтись
>>sniknik
почитай хылп про objectы, что значит не полноценный vmt? такойже как у классов, только без шушеры по отрицательному смещению
← →
Сергей М. © (2008-10-16 18:51) [57]
> просто так (16.10.08 18:29) [56]
> мне ненужно 50000 разных объектов, нужно 50000 точек
Чудесно.
Возьми да организуй массив структур, описывающих точку.
Нахрен тебе массив объектов-то ? Точка ведь расчудесно описывается структурой..
Нахрен точке методы, да еще и виртуальные ?
← →
Сергей М. © (2008-10-16 18:54) [58]
> под разные объекты в обном массиве без указателей не обойтись
Ну а чтоже ты тогда тычешь свою точку в кач-ве примера ?
← →
просто так (2008-10-16 19:15) [59]Серега. топик про ошибку в обжектах, а не про убеждения меня что мне нужно, что ненужно
← →
Сергей М. © (2008-10-16 19:26) [60]Нет там ошибки. Тебе уже сказали про "честность" в Д2009.
← →
sniknik © (2008-10-16 19:32) [61]> что значит не полноценный vmt?
а вот то что я вижу, и примерами пытаюсь "донести", адрес записывается как переменная, и при вызове не используется. (в 2009м возможно уже не так)
это полноценно?
> только без шушеры по отрицательному смещению
так эта "шушера" реально будет только один раз для класса, см.
Sapersky (16.10.08 15:55) [49]
где он про vmt пишет. это как раз к классам относится.
← →
просто так (2008-10-16 20:03) [62]Уважаемый sniknik, данный метод 100% виртуальный, то что вы этого не увидели - или не туда смотрели или (менее вероятно) происки оптимизатора. VMT для обжектов - хранит адреса виртуальных методов и инициализируется при компиляции. ссылка на vmt которая добавляется к полям объекта при первом появлении виртуального метода - инициализируется конструктором (адрес vmt передается конструктору в регистре edx при вызове)
← →
просто так (2008-10-16 20:05) [63]>>Сергей М.
прежде чем так категорично заявлять, я бы на вашем месте качнул 2009 и проверил))
← →
GrayFace © (2008-10-16 20:14) [64]В D2006, похоже, тоже VMT у объектов не инициализируется. SizeOf вообще мусор возвращает. И property в объектах еще в D7 не работали, в D2006, правда, не проверял.
Sapersky (16.10.08 15:55) [49]
Вызовы "изнутри" объекта динамические. Т.е. если в объекте-родителе есть вызов виртуальной функции, которая замещена в наследнике, вызовется именно функция наследника.
Хотя и не полноценный полиморфизм, но иногда может быть полезно.
Полиморфизм, вроде, полноценный. Если передавать ссылку, пытается вызвать виртуально.
Сергей М. © (16.10.08 18:51) [57]
Нахрен точке методы, да еще и виртуальные ?
Обычные методы, безусловно, нужны. Например, свойство Length.
sniknik © (16.10.08 19:32) [61]
а вот то что я вижу, и примерами пытаюсь "донести", адрес записывается как переменная, и при вызове не используется. (в 2009м возможно уже не так)
это полноценно?
Дак подебаж и все увидешь - записывается адрес VMT, а не метода. Не используется только когда это не нужно - если тип объекта очевиден.
Посмотри SizeOf у этого:type
TA = object
q:integer;
function aaa:int; virtual;
procedure bbb; virtual;
end;
← →
Sapersky (2008-10-16 20:14) [65]и то что эти байты не цепляются ко всем объектам это ты не подумав сказал...
Я несколько другое говорил:
VMT не цепляется полностью к каждому объекту
т.е. о том, что размер объекта не зависит от кол-ва виртуальных функций в нём. Мне показалось, что здесь вы утверждали обратное:
вот тебе те 4 байта которые ты "экономил" на указателе отказавшись от динамических классов. а если ещё такая процедура не одна...
Пример дин. вызова со статическим объектом у меня приблизительно такой:
TMyObject = object
i : Integer;
constructor Create;
destructor Destroy; virtual;
procedure DoSmth; virtual;
end;
TMySecObj = object (TMyObject)
procedure DoSmth; virtual;
end;
constructor TMyObject.Create;
begin
DoSmth; // здесь вызовется DoSmth от TMySecObj через VMT
end;
Var mo : TMySecObj;
begin
mo.Create;
Полагаю, что при динамическом создании объектов "внешние" вызовы виртуальных функций у них тоже будут динамическими. Иначе непонятно, зачем в книгах по Турбо-Паскалю употреблялось слово "полиморфизм" :)
← →
GrayFace © (2008-10-16 20:17) [66]просто так, и все-таки когда нужны object"ы (плохи record"ы с классами)?
← →
oxffff © (2008-10-16 20:31) [67]
> просто так (13.10.08 21:08)
12.0.3155.16733.
Полет нормальный.
ABase=object
procedure abc;virtual;abstract;
end;
PABase=^ABase;
ADerived=object(ABase)
procedure abc;virtual;
constructor create;
end;
{ ADerived }
procedure ADerived.abc;
begin
showmessage("ADerived");
end;
constructor ADerived.create;
begin
inherited;
//Do nothing
end;
procedure TForm2.FormCreate(Sender: TObject);
var a:ADerived;
p:PABase;
begin
p:=@a;
a.create;
p.abc;
end;
← →
oxffff © (2008-10-16 20:46) [68]Динамическое создание
var
pd:^ADerived;
begin
new(pd,create);
dispose(pd);
d2009 полет нормальный. Буду после 22-00.
← →
просто так (2008-10-16 20:51) [69]>>oxffff
а из [1]? c пределениями в разных файлах?
>>GrayFace
Да сколько можно? любой случай большого массива маленьких данных. рекорды мне неудобны по причине отсутствия поддержки рекордов с методами в fpc и delphi < 2007. виртуальные методы в примере только чтобы показать ошибку
← →
Сергей М. © (2008-10-16 21:03) [70]
> просто так (16.10.08 20:05) [63]
Только лишь ради проверки твоей блажи ?
А оно мне надо ?)
← →
GrayFace © (2008-10-16 21:07) [71]просто так (16.10.08 20:51) [69]
Да сколько можно? любой случай большого массива маленьких данных. рекорды мне неудобны по причине отсутствия поддержки рекордов с методами в fpc и delphi < 2007.
Столько, сколько нужно чтобы получить ответ. Тогда лучше делать условную компиляцию с object"ами для старых версий и record"ами для новых.
← →
просто так (2008-10-16 21:17) [72]>>Только лишь ради проверки твоей блажи ?
не, чтоб не быть голословным
← →
oxffff © (2008-10-16 23:01) [73]
> просто так (16.10.08 20:51) [69]
> >>oxffff
> а из [1]? c пределениями в разных файлах?
Да действительно есть проблема.
Она заключается в том, что при инициализации экземпляра в метаклассе не корректно содержится информация о смещении VMT в экземпляре.
В метаклассе отступ +0 от начала экземпляра, а при вызове используется отступ +4(где соответственно мусор).
НО!!!
Чуть чуть шаманства и твоя проблема решена.
Сделай так.
zBase=object
procedure EmptyVirtual;virtual;
end;
zgui=object(zBase)
{ zBase }
procedure zBase.EmptyVirtual;
begin
//
end;
Аплодисменты!!! Занавес!!!!
← →
oxffff © (2008-10-16 23:21) [74]
> просто так
Писать в QC смысла нет, поскольку там администрируют реальные дятлы, им объяснишь в чем проблема, они скажут только проблема не зафиксирована.
Например я писал, что невиртуальный вызов GetEnumerator виртуального метода в конструкции for in. Сказали мы не видим проблемы. Но ... поправили в будущих версиях.
Писал им про потенциальные утечки памяти при многократном вызове конструктора record. Сказали мы не видим проблемы. Не знаю поправили или нет сейчас. Вообщем забил я на QС и на всю их команду.
Дятлы одним словом. Честно наболело.
← →
oxffff © (2008-10-16 23:24) [75]
> oxffff © (16.10.08 23:21) [74]
Слава богу, что хороший DRUM&BASS радует душу.
← →
просто так (2008-10-16 23:48) [76]>>Сделай так.
т.е. пустой предок? непомогло, помогает только всё собрать в один файл
← →
oxffff © (2008-10-16 23:51) [77]
> просто так (16.10.08 23:48) [76]
Не пустой предок, а прекод с виртуальным методом. Что зафиксировать смещение VMT в 0.
← →
oxffff © (2008-10-16 23:53) [78]
> просто так (16.10.08 23:48) [76]
В итоге zguis.pas выглядит
type
zBase=object
procedure EmptyVirtual;virtual;
end;
zgui=object(zBase)
test:pointer;
procedure crash;virtual;
constructor create;
end;
implementation
procedure zgui.crash;
begin
test:=nil;
end;
constructor zgui.create;
begin
crash; //тут уже нет AV
end;
{ zBase }
procedure zBase.EmptyVirtual;
begin
//
end;
← →
просто так (2008-10-17 00:35) [79]спсб, вроде заработало. но это тоже не выход((
← →
Германн © (2008-10-17 01:35) [80]
> просто так (17.10.08 00:35) [79]
>
> спсб, вроде заработало. но это тоже не выход((
>
А какой выход ты хотел бы? Волшебную палочку?
P.S. Пустопорожняя тема, а длится уже более трёх суток. И мой пост уже 80-й.
Страницы: 1 2 3 вся ветка
Текущий архив: 2009.11.15;
Скачать: CL | DM;
Память: 0.65 MB
Время: 0.017 c