Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-46784
Yanis
2003-05-01 13:58
2003.05.15
Как сохранить файл с правильным расширением?


3-46578
Silver_
2003-04-23 10:39
2003.05.15
TADODataSetEvents как сделать или где взать


14-46962
Zhenka
2003-04-26 12:37
2003.05.15
Добрый день. Господа кто нибудь знает как работать с БЛОБ


14-46984
VEG
2003-04-13 00:30
2003.05.15
Что вы думаете об этом архиваторе?


7-47011
eLVik
2003-03-19 19:28
2003.05.15
Реестр





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский