Форум: "Основная";
Текущий архив: 2003.05.15;
Скачать: [xml.tar.bz2];
ВнизКак создать класс без наворотов, что бы память только под данные? Найти похожие ветки
← →
bxMax (2003-04-30 16:19) [0]Мне, для создания разветвленной структуры хочется создать простой класс содержащий данные - родительский элемент, следующий элемент и еще чего нибудь маленькое. Всего байт 20. Процедуры для обработки - все статические. Когда я создаю класс, автоматически создается куча таблиц, для каждого экземпляра класса создается таблица указателей на эти таблицы.... Ужасть короче. Экземпляр займет раз в пять больше места чем мне надо. А экземпляров предполагается пару сотен тысяч, может миллионов...
Можно сделать глобальные процедуры конечно и записи вместо класса, но ведь не красиво. Как быть... Наплевать на Дельфи и писать на С++?
← →
Smithson (2003-04-30 16:20) [1]record попробуй
← →
bxMax (2003-04-30 16:28) [2]К сожалению в рекорд нельзя определить методы для обработки данных. :-(
← →
Smithson (2003-04-30 16:30) [3]Тогда наследуйся от TObject и не используй dinamyc и virtual процедур. Но если так критичен размер структуры, что мешает сделать record и методы для обработки как обычные (не объектные) процедуры?
← →
Digitman (2003-04-30 16:39) [4]
> bxMax
> в рекорд нельзя определить методы для обработки данных
это почему же нельзя-то ?
что мешает объявить процедурный тип и завести в записи поле такого типа ?
← →
Игорь Шевченко (2003-04-30 16:50) [5]bxMax (30.04.03 16:19)
object ?
← →
Digitman (2003-04-30 16:51) [6]type
PMyRecord = ^TMyRecord;
TMyMethod = procedure(Instance: PMyRecord; Param: Integer);
TMyRecord = packed record
SomeField: Integer;
SomeMethod: TMyMethod;
end;
procedure RecMethod(Instance: PMyRecord; Param: Integer);
begin
Instance.SomeField := Param;
end;
procedure TForm1.Button4Click(Sender: TObject);
var
MyRecord: PMyRecord;
begin
New(MyRecord); //аллокация памяти под экз-р
MyRecord.SomeMethod := RecMethod; // иниц-ция экземпляра
try
MyRecord.SomeMethod(MyRecord, 5); // вызов "метода"
finally
Dispose(MyRecord);
end;
end;
← →
bxMax (2003-04-30 17:04) [7]Игорь Шевченко: попробую что оно из себя, но смущает что object "только для совместимости"
Digitman: Спасибо за старания, но вы не вникли в смысл вопроса. Ваш метод нужен как раз в случае если я хочу сделать аналог динамических методов. А в моем случае с record проще тогда использовать обычные (не объектные) процедуры.
Smithson: Что мешает испоьзовать обычные? Хотябы желание инициализировать объект при помощи конструктора, вместо постоянных вызовов процедур инициализации везде где я создаю объект.
Вощем, я разочарован. В сях все красивше гораздо. Конечно, если не переубедите.
← →
Fantasist. (2003-04-30 17:08) [8]
> для каждого экземпляра класса создается таблица указателей
> на эти таблицы
А с чего такая уверенность, что так много? Какие указатели нужны экземпляру класса? Указатель на таблицу виртуальных методов, на таблицу динамических методов, указатель на информацию о типе. Динамические методы можно не использовать, RTTI отключить, от виртуальных функций никуда не денешься, итого остается один указатель на каждый экземпляр - 4 байта. У тебя класс 20 байт, если бы выравнивание по 8 байт, то было бы вообще все равно. Это, конечно, если компилятор не такой тормозной, чтобы включать указатели которые не используются. Я думаю, что не такой.
← →
Digitman (2003-04-30 17:13) [9]
> bxMax
динамическим назначением реального адреса метода ты в дан.случае будешь эмулировать статику.
сделай отдельную проц-ру инициализации экз-ра - и всех делов !
← →
bxMax (2003-04-30 17:35) [10]Fantasist: В разделе справки "объект паскаль" - "использование памяти" расписана таблица которая создается для каждого класса. Независимо от того, какие возможности я хочу использовать, размер ее не изменяется. Вот тип object к сожалению там не расписан. Наверное как устаревший. :-(
Digitman: Не для того создано ООП, чтобы я делал отдельные процедуры инициализации, потом еще и вызывал их каждый раз! Тогда уж можно и на ассемблере писать, вообще неразрешимых проблем не будет.
Уйду я от вас. К сям. И чего на етот дельфи мода такая...
← →
Smithson (2003-04-30 17:40) [11]Иди, спаниель несчастный... Подумай тока, чем конструктор отличается от процедуры.
← →
Digitman (2003-04-30 17:43) [12]
> bxMax
иди-иди !) по средам здесь не подают !))))
← →
vuk (2003-04-30 17:47) [13]to bxMax:
>Экземпляр займет раз в пять больше места чем мне надо.
Дяденька, извиняюсь, но InstanceSize для TObject = 4. Так что
не надо про 5 раз.
← →
bxMax (2003-04-30 17:48) [14]Smithson - спасибо за предложение, но я об этом размышлял лет 8 назад. В настоящее время нет такой необходимости. Просто вот сунулся в Дельфи для общего развития, и гляжу что элементарные вещи здесь по простому сделать нельзя.
← →
Fantasist. (2003-04-30 17:48) [15]
> расписана таблица которая создается для каждого класса
Вот, вот. Для каждого класса. Не для экземпляра. В экземпляре создается только указатель на эту таблицу.
← →
Anatoly Podgoretsky (2003-04-30 17:50) [16]bxMax (30.04.03 17:48)
Тяжелое наследие прошлого.
← →
LEON (2003-04-30 17:56) [17]смотрели KOL?
там всюду objectы
← →
bxMax (2003-04-30 18:37) [18]Fantasist: Прости друг, но эта таблица содается именно для экземпляра класса. И содержит она указатели на таблицы общие для класса. Я еще понимаю разницу.
vuk: Не верь тому что тебе возвращают глупые функции. Загляни в system.pas и поймешь что экземпляр не может занимать меньше 88 байт.
← →
vuk (2003-04-30 18:47) [19]to bxMax:
>Не верь тому что тебе возвращают глупые функции.
Функции не глупые. На их основе делается выделение памяти под экземпляр. Содержимое system.pas и объем выделяемой памяти это только подтверждают. :o)
← →
Fantasist. (2003-05-01 01:09) [20]
> Прости друг, но эта таблица содается именно для экземпляра
> класса
Эх-ех. Тяжело с народом общаться. :) Ну скажи, какая такая таблица нужна именно для каждого экземпляра (ну чисто логически)? Или покажи мне этот раздел где ты такое вычитал. А потом действительно посмотри в system.pas, и посмотри как выделяется память под класс.
Вот я даже сам в хелп залез. :) Цитата:
The first 4-byte field of every object is a pointer to the virtual method table (VMT) of the class. There is exactly one VMT per class (not one per object); distinct class types, no matter how similar, never share a VMT. VMTs are built automatically by the compiler, and are never directly manipulated by a program. Pointers to VMTs, which are automatically stored by constructor methods in the objects they create, are also never directly manipulated by a program.
The layout of a VMT is shown in the following table...
На самом деле я ошибался - указатель всегда в классе один, а уж указатели на Type Info и dynamic method table находятся в той таблице, на которую этот указатель и указывает (находиться по отрицательному смещению).
← →
Тих (2003-05-01 11:41) [21]Сдается, что сабжетворитель и ++ знает по верхам, а сюда залез просто пальчики растопырить
← →
vuk (2003-05-01 13:44) [22]to All:
Воинствующая некомпетентность помните как называется? :o)
← →
Юрий Зотов (2003-05-01 13:58) [23]> bxMax (30.04.03 17:48)
> сунулся в Дельфи для общего развития, и гляжу что элементарные
> вещи здесь по простому сделать нельзя.
Конечно, нельзя, если этих элементарных вещей просто не знаешь и не понимаешь. Например, что такое класс объекта, что такое его экземпляр, чем они друг от друга отличаются, что такое VMT и к чему она относится, что возвращает "глупая" InstanceSize и пр.
Только вот что - когда "общее развитие" такое, что не знаешь элементарных вещей, то никакие Си тоже не помогут. Так что - вперед и с песней. Флаг в руки и барабан на шею, как говорится. Попутного Вам за воротник!
Вспоминаются две вещи.
1. Басня Крылова "Мартышка и очки":
"К несчастью, то ж бывает у людей -
Как ни полезна вещь, цены не зная ей
Невежда про нее все к худу клонит.
А ежели невежда познатней -
Так он ее еще и гонит."
2. Рекламный ролик на тему:
- Ненавижу кошек!
- Ты просто не умеешь их готовить.
← →
KSergey (2003-05-02 12:31) [24]Эх, обидно...
Когда увидел, что Юрий Зотов что-то ответил - надеялся, что он сейчас все растолкует, так хоть и я знать буду ;)
Но к сожалению - нет.
Ладно, будем сами читать при случае (а было бы приятно вот так вот без затрат и на готовенькое... ;)
← →
vuk (2003-05-02 15:15) [25]to KSergey:
А что здесь разжёвывать-то? Размер памяти, выделяемой под экземпляр равен суммарному размеру полей экземпляра + 4 байта (указатель на VMT) + выравнивание (зависит от установок компилятора).
← →
KSergey (2003-05-02 15:26) [26]> vuk © (02.05.03 15:15)
Не в обиду будь сказано, хлтелось это услышать от авторитетного человека. Чтобы самому не проверять. Ведь всегда информацию с форумов приходитя множить на некий коэффициент достоверности...
← →
vuk (2003-05-02 15:40) [27]Ну так самому проверять - оно ж завсегда полезнее. :o)
← →
Юрий Зотов (2003-05-02 16:19) [28]Дык... а что тут отвечать-то? Все просто, как арбуз.
Код методов, VMT, RTTI и т.п. относятся к самому КЛАССУ, а не к его ЭКЗЕМПЛЯРАМ (собственно, класс - это и есть указатель на VMT). Поэтому в программе все это существует в единственном числе на каждый используемый в ней класс, даже если в ней создан хоть миллион объектов данного класса. Для того методам класса и нужен параметр Self - через него они узнают с каким именно экземпляром класса идет работа в данный момент (то есть, при обращении к полям экземпляра компилятор использует этот адрес, как базовый и, добавляя к нему смещение поля, получает адрес самого поля).
А экземпляр объекта содержит именно данные (точнее, поля) и ничего более. Плюс, правда, еще 4 байта - это ссылка на класс, к которому данный экземпляр относится (хранится по нулевому смещению, как неявное поле). Размер экземпляра вычисляется на этапе компиляции, хранится в VMT данного класса по смещению vmtInstanceSize и возвращается методом InstanceSize.
Поэтому TObject.InstanceSize и возвращает 4 - это размер ссылки на класс, а явных полей у TObject нет. А вот если сделать такой класс:
TMyClass = class(TObject)
private
FBooleanField: boolean;
end;
то размер его экземпляров будет зависеть от того, выравнивает ли компилятор поля объекта и, если да, то как именно он это делает. Если не выравнивает - получим 5 байт, при выравнивании на границу двухбайтового слова - 6 байт, а при выравнивании на границу четырехбайтового слова - 8 байт. Вполне обычная и нормальная вещь для любого компилятора.
И мне очень странно, что, не зная даже этой элементарной азбуки (что доказывает сам вопрос), человек берется судить о том, чего не знает, ругает Delphi, и спорит с теми, кто пытается ему объяснить его заблуждение. При таком подходе ему действительно не поможет ни Си, ни что угодно другое. Пока он не изменит сам подход - а после этого, глядишь, и Delphi окажется не такая уж плохая. При ближайшем рассмотрении.
← →
ErikIvanov (2003-05-02 16:23) [29]Я что ты такое пишеш, что для тебя так вожна память? Мне кажется это чисто академические эксперементы! Токда тебе надо в другой форум. Я тоже люблю экономно все делать, но ночего плохого невижу в наследовании от TObject. А если надо много памяти, то пишу класс который работает с Array of record вот так!
← →
KSergey (2003-05-02 16:28) [30]vuk © (02.05.03 15:15)
Юрий Зотов © (02.05.03 16:19)
Спасибо!
← →
MsGuns (2003-05-02 16:34) [31]Положу свои 3 коп.
Ощущение такое, что цель забыта ради средств. Т.е. вместо того, чтобы сделать просто и надежно (через рекорды, массивы и т.д.), делается попытка "окрасивить". Вместо простого и надежного алгоритма создаются на ровном месте классы, к ним методы и т.д. - и это для того, чтобы сохранить в памяти большой объем вполне линейной структурированной информации.
Типа для распилки одного бревна строится пилорама.
← →
vuk (2003-05-02 16:54) [32]to MsGuns:
Вообще говоря, есть такая штука, инкапсуляция называется (объединение кода и данных в одном месте). Это к основам ООП относится. И опыт показывает, что это и в отладке и в использовании объекты проще, чем сочетание записей и процедур их обработки.
>и это для того, чтобы сохранить в памяти большой объем вполне
>линейной структурированной информации.
Читаем внимательно исходное сообщение и видим:
для создания разветвленной структуры хочется
То есть структура как раз нелинейная.
← →
MsGuns (2003-05-02 17:20) [33]>vuk © (02.05.03 16:54)
Спасибо, что объяснил мне понятие икапсуляции ;)) И про ООП - чесслово, первый раз слышу ;)
>Читаем внимательно исходное сообщение и видим:
>для создания разветвленной структуры хочется
>То есть структура как раз нелинейная.
К сожалению, не обладаю телепатическим даром и не смог определить, что речь идет о нелинейной структуре. Лично я не считаю дерево, листьями которых служат однотипные (т.е. аналогичные по составу) наборы форматов данных, нелинейной структурой. Хотя, конечно, могу и ошибаться.
← →
vuk (2003-05-02 17:46) [34]to MsGuns:
>Спасибо, что объяснил мне понятие икапсуляции ;))
Всегда пожалуйста, приходите к нам ещё. :o)
Просто если удобнее работать с объектами, то почему делать иначе? 4 Байта экономить? Ну так менеджер динамической памяти все услилия по экономии нескольких байтов практически к нулю сведёт - у него свои правила.
Опять же, кто его знает, как потом дело обернется, может человеку структуры придется неоднотипные делать или обработку разную прикручивать... Но это уже измышления, так сказать. :o)
← →
Fantasist. (2003-05-02 18:37) [35]Полностью согласен с vuk © - я практически всегда использую объекты всместо рекордов там, где их нужно динамически создавать. Удобно и инициализировать, и обработку какую небольшую прикрутить. Единственно, что не нравиться - отсутсвие автоматических объектов, то есть классы всегда надо самому создавать в куче и самому их освобождать.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.05.15;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.01 c