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

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.012 c
6-46869
Карелин Артем
2003-03-17 15:58
2003.05.15
Получение статуса RAS.


3-46606
Rol
2003-04-22 11:08
2003.05.15
TIBDataSet.UpdateRecordTypes


3-46624
Новичок в СУБД
2003-04-24 11:12
2003.05.15
Ошибка при работе с индекированной таблицей


1-46799
Nikos
2003-05-02 13:03
2003.05.15
как работать с фалами ini


14-46964
processor
2003-04-26 23:00
2003.05.15
Есть ли отличие процессоров AMD и Intel?