![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Хранение Integer в Combobox [D6, Win2k]
Влад Утюмов © (2002-09-27 07:55:00)Подскажите новичку, плз наиболее прямой способ решения задачи.
Есть комбобокс на форме. В нем, кроме строк, хочется хранить целочисленные значения (ключи таблицы в БД, но это не важно). Из документации выясняю, что есть
AddItem(Item: String, AObject: TObject)
Вроде то что надо. То что Integer это не TObject - не беда, полминуты - готова обертка вокруг Integer, унаследованная от TObject
И тут натыкаюсь на то, что TStrings не владеет обжектами, что их надо самому удалять. А чтобы самому удалять, надо их еще где-то хранить, и получается уже бред.
Лезут в голову разные мысли, типа поменять поведение TComboBox путем наследования или складывать ссылки на обжекты в отдельную корзину, а потом вытряыхивать разом, или хранить ключи вообще отдельно, в массиве каком-нибудь.
Но думается, что у такой тривиальной и распространенной, ИМХО, задачи не должно быть сложного и уродливого решения. Душа желает простоты.
Влад.
kronprince (2002-09-27 12:59:00) [1]TTCustomDelphiMaster © (27.09.02 12:38)
Это как Вы заметили писалось для специфичных нужд
Вырезать легче :)
TTCustomDelphiMaster (2002-09-27 12:38:00) [2]kronprince © (27.09.02 12:08)
> Подскажите новичку, плз наиболее прямой способ решения задачи...
> ... не должно быть сложного решения. Душа желает простоты.
MBo (2002-09-27 12:35:00) [3]Хорошо, пусть потребуется хранить не 4-байтовое, а другое (больше размера указателя).
Опять же класс ни к чему
type PInt64=^Int64;
var p:PIint64;
new(p);
p^:=12345678901234;
Items.AddObject("ww",TObject(p));
...
Int64Var:=Pint64(Items.Objects[i])^;
точно так же и с записями - определяем тип указателя на нее и вперед.
Класс же нужен в тех случаях, когда соотв. объект (в широком смысле) должен быть активен или обеспечивать нетривиальный доступ к своим полям.
kronprince (2002-09-27 12:08:00) [4]TTCustomDelphiMaster © (27.09.02 12:02)
TDictionary = class
protected
sFieldID :string;
sFieldName:string;
private
aiRec : TAInteger; // ID_REC
asName: TAString; //
TTCustomDelphiMaster (2002-09-27 12:02:00) [5]kronprince © (27.09.02 11:34)
Класс не надо. Можно массив.
Anatoly Podgoretsky (2002-09-27 11:56:00) [6]Юрий Зотов © (27.09.02 11:11)
Давайте, но начнем с того, что суть моего замечания состоит в том, что закладываться на внутрннее представление не стоит, тем более на что то еще не существуещее. Возможно будет достаточно и этого замечания
Давайте уточним позиции.
Вы полагаете, что возврат к сегментной адресации возможен? Или к любой ей подобной - то есть, не прямой flat?
Ходят и такие слухи про новые 64 битные процессоры, но я не думаю, зато гораздо важнее другое, перенос между платформами
Если да - Вы правы. Если нет - прав я.
Потому что, как Вы прекрасно понимаете, никаких Pointer"ов железо вообще не знает - только целые числа, интерпретируемые, как адреса. И понятно, что наибольшая производительность (а к ней, естественно, всегда стремятся) достигается тогда, когда эти числа есть родные машинные слова, и когда используется flat-адресация.
Прекрасно это понимаю, но Integer и Pointer не обязательно должны быть одинаковый длины.
Ведь адресация Seg:Offs появилась не от хорошей жизни, а просто потому, что 64-х Кб, когда-то считавшихся для персоналок достаточными, вдруг оказалось мало. И надо было быстро ликвидировать противоречие, не переделывая в корне разрядность.
Я знаю откуда это и почему, и также знаю почему не спешили делать другое. Д1 наглядный пример.
А как только пошла 32-битная разрядность, так противоречие автоматически устранилось и снова вернулись к flat. И, думаю, теперь уже навсегда.
Я тоже очень на это надеюсь, хотя если взглянуть глубже, от сегментных регистров мы никуда не делись, просто они напрямую не используются и запрещены к использованию, на самом деле мы имеем селектор+смещение в 32 бита (упрощенно конечно), первая половина нас не интересует, если мы не работает на чрезвычайно низком уровне.
Так для информации: 386 процессор в состоянии адресовать до 14 террабайт виртуальной памяти, не знаю используется где либо такая возможность.
Ну и в заключение, то что в начале, для безопасного кодане стоит ставить знак равенства между Integer и Pointer. Думаю с выделенным ты согласен. И второй момент безопасности здесь Integer & TObject тоже не хорошо, хотя практика распространенная.
kronprince (2002-09-27 11:34:00) [7]2Юрий Зотов © (27.09.02 10:56)
Извините Юрий - но задача была не про сложение integer а облегчение работы ComboBox с некоторым полем из базы :-\
И в этом случае лучше использовать именно класс
Т.к. может понадобиться не только integer но например Extended или Currency
Юрий Зотов (2002-09-27 11:26:00) [8]AddObject(строка, TObject(число));
Чтение: Integer(Objects[i]).
Вот и все проблемы. Таким же образом можно вместе со строкой хранить любые данные длиной не более SizeOf(TObject) - то есть, на сегодня 32 бита. Хоть числа, хоть boolean.
Влад Утюмов (2002-09-27 11:17:00) [9]Неожидал такой бурной дискуссии =)
Внесу немного ясности в спор об размерности Integer.
У меня это ключ таблицы БД. В настоящий момент он имеет размерность 32 бита, но в некоторых ситуациях может оказаться и 64 (распределенные БД например, или очень большие). Поэтому я определил
type oid_t = integer;
(надеюсь не ошибся при переводе с С++ на паскаль), оставив себе пути к отступлению. Этот oid_t я и хочу хранить в комбо, сорри за то то ввел публику в заблуждение.
Получается: кастить его к указателю нежелательно.
Если же число хранить в строке то где хранить сами строки. Или же использовать кодирование типа
15|Строка которую хочу показать
или вообще строки хранить отдельно (уж лучше отдельно хранить цифирьки).
Спасибо всем. Понял.
Юрий Зотов (2002-09-27 11:11:00) [10]> Anatoly Podgoretsky © (27.09.02 10:37)
Давайте уточним позиции.
Вы полагаете, что возврат к сегментной адресации возможен? Или к любой ей подобной - то есть, не прямой flat?
Если да - Вы правы. Если нет - прав я.
Потому что, как Вы прекрасно понимаете, никаких Pointer"ов железо вообще не знает - только целые числа, интерпретируемые, как адреса. И понятно, что наибольшая производительность (а к ней, естественно, всегда стремятся) достигается тогда, когда эти числа есть родные машинные слова, и когда используется flat-адресация.
Ведь адресация Seg:Offs появилась не от хорошей жизни, а просто потому, что 64-х Кб, когда-то считавшихся для персоналок достаточными, вдруг оказалось мало. И надо было быстро ликвидировать противоречие, не переделывая в корне разрядность.
А как только пошла 32-битная разрядность, так противоречие автоматически устранилось и снова вернулись к flat. И, думаю, теперь уже навсегда.
Юрий Зотов (2002-09-27 10:56:00) [11]> всего лишь с целью запихивания повторяющихся кусков кода и
> популярных методов работы в один класс
Для Integer Ваши "повторяющиеся куски кода и популярные методы работы" сводятся всего лишь к арифметическим операциям.
Хотите написать класс и вызывать его метод Add - пожалуйста, флаг Вам в руки. А я, с Вашего разрешения, уж как-нибудь буду писать по-старинке - просто "+". Думаю, мой вариант будет порождать машинный код примерно на три порядка короче и на пять порядков быстрее. Потому что я предпочитаю писать понятный и эффективный код, а не говорить красивые слова об объектах и технологиях "вообще", безотносительно конкретной задачи.
Поскольку понимаю, что гвозди лучше забивать действительно молотком, а не табуреткой. А вот для сидения молоток как-то не приспособлен, для сидения как раз табуретка лучше.
Не верите? Проверьте.
:о)
Anatoly Podgoretsky (2002-09-27 10:37:00) [12]Юрий Зотов © (27.09.02 10:27)
Это не совсем так, возьмем для примера 8 битные процессоры, пускай даже от фирмц Интел, адресация была и 12 бит и 16 бит.
Кроме того если посмотрим 16 бит и процессоры 86, 286, 386
Адресная шина 16, 20, 32
Указатель 32 бита seg:ofs
Имподьзовать приведение конечно можно, но следует понимать, что возможно это не будет работать в других версиях
KIR (2002-09-27 10:33:00) [13]
var
IDList: TStringList
в предыдущем ответе конечно лишнее, sorry :)
kronprince (2002-09-27 10:32:00) [14]2Юрий Зотов © (27.09.02 10:27)
>Но вот плодить объектную оболочку вокруг Integer...
Извините, плодить - да, всего лишь с целью запихивания повторяющихся кусков кода и популярных методов работы в один класс
KIR (2002-09-27 10:31:00) [15]Я вообще в этом случае (конкретно когда надо в ComboBox выводить какое либо поле из БД и еще где хранить ключ) делаю так:
Предположим есть некий запрос из которого и надо брать требуемые поля (MyQuery);
Объявляю глобальную переменную IDList: TStringList;
по событию формы OnCreate -> IDList := TStringList.Create;
Затем:
procedure TForm.FillComboBox;
var
IDList: TStringList;
begin
IDList.Clear;
ComboBox1.Clear;
MyQuery.Close;
MyQuery.ExecSQL;
MyQuery.Open;
MyQuery.First;
While not MyQuery.Eof do
begin
ComboBox1.Items.Add(MyQuery["StringField"]);
IDList.Items.Add(IntToStr(MyQuery["ID"]));
MyQuery.Next;
end;
end;
А затем по событию OnClick ComboBox"a:
IDList.ItemIndex := ComboBox1.ItemIndex;
В результате в IDList всегда имею ID нужной записи (ну естественно ID := StrToInt(IDList.Items[IDList.ItemIndex]);
Юрий Зотов (2002-09-27 10:27:00) [16]> Ну ведь был же integer двухбайтовым, сейчас он
> четырёхбайтовый. И очень вероятно, что грядут времена
> восьмибайтовых интов...
И ничего не изменится. Во все времена Integer соответствовал машинному слову. Pointer тоже. Так было и так будет, поскольку это один из основополагающих принципов. Поэтому размеры Integer и Pointer всегда будут совпадать, а только это и требуется.
Но вот плодить объектную оболочку вокруг Integer...
Можно, конечно, и гвозди табуреткой забивать. Но молотком лучше.
Anatoly Podgoretsky (2002-09-27 10:26:00) [17]MBo © (27.09.02 09:50)
Это generic тип, так что такая возможность очень вероятноь и расчитывать на соместимость по размеру, преобразованию лучше не стоит
KSergey (2002-09-27 10:22:00) [18]2 Толик © (27.09.02 10:02)
В принципе вы правы, но как правило программа пишется под определенную версию D, где на таких нюансах вполне можно сыграть (я имею в виду совпадение размеров). При этом если станет small - не страшно, все равно влезет.
qube (2002-09-27 10:08:00) [19]>Ну ведь был же integer двухбайтовым, сейчас он четырёхбайтовый. И >очень вероятно, что грядут времена восьмибайтовых интов...
Тогда, вероятно, и указатели станут 8-байтовыми, а кроме того, вопрос был о комбобоксе, и кажется мне, что добавлять туда числа порядка 2-х миллиардов никто не собирается.
Толик (2002-09-27 10:02:00) [20]to MBo © (27.09.02 09:50)
Ну ведь был же integer двухбайтовым, сейчас он четырёхбайтовый. И очень вероятно, что грядут времена восьмибайтовых интов...