Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как организовать структуру..? умеющую работать с разными типами данных 
:(
    Опции темы
Belij
  Дата 25.12.2003, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 19.12.2003

Репутация: нет
Всего: нет



Есть два объекта - один класс управляет элементами очереди (в ее классическом понятии),
второй управляет всей очередью и данными. Очередь содержит ссылки на область памяти,где хранятся эти данные разных типов. Так вот, очередь должна "кушать" элементы типа byte, word,longword,single, double. Первоначально я решил использовать просто MyType = Variant; а Data : MyType....но так нельзя...структура должна четко знать, какого типа элемент ей скормили чтобы выделит память. Все это пишется через console app через WinAPI. Помогите, плиз, как организовать такую структуруconfused.gif

butbut.gif


PM MAIL   Вверх
man2002ua
Дата 25.12.2003, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 943
Регистрация: 12.11.2002
Где: Киев

Репутация: нет
Всего: 2



при создании элемента очереди передавай указатель на данные и их размер. В очереди будет храниться указатель на данные и размер их.


--------------------
"Нет ничего более постоянного, чем временное"
PM MAIL   Вверх
AntonSaburov
Дата 25.12.2003, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: нет
Всего: 118



Цитата
Помогите, плиз, как организовать такую структуру


Очередь будет хорошо работать только если все элементы унаследованы от Object. Может тебе стоит наделать простеньких классов для каждого или сделать один для хранения любого элементарного типа.
PM MAIL WWW ICQ   Вверх
p0s0l
Дата 25.12.2003, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



А можно еше наваять что-нибудь типа этого:
Код

type
 TSomeData = packed record
   case integer of
     0 : (ValueByte : Byte);
     1 : (ValueWord : Word);
     2 : (ValueDWord : DWord);
     3 : (ValueSingle : Single);
     4 : (ValueDouble : Double);
 end;

 TElement = packed record
   Data : TSomeData;
   DataType : byte;
 end;


// Пример как использовать:

var
 El : TElement;
...
begin
...
 case El.DataType of
   0 : PrintThis(El.Data.ValueByte);
   1 : PrintThis(El.Data.ValueWord);
   2 : PrintThis(El.Data.ValueDWord);
   3 : PrintThis(El.Data.ValueSingle);
   4 : PrintThis(El.Data.ValueDouble);
 end;
end;

Т.е. смотришь DataType, если = 0, то этот элемент - это байт, если = 1, то элемент - это слово...
Только в таком случае каждый элемент (независимо от его типа) будет иметь один и тот же размер = SizeOf(TElement) = 9 байт.

Это сообщение отредактировал(а) p0s0l - 25.12.2003, 14:03


--------------------
С уважением, г-н Посол.
PM   Вверх
DonPager
Дата 25.12.2003, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Колдырь
**


Профиль
Группа: Участник
Сообщений: 327
Регистрация: 28.3.2003
Где: Воронеж

Репутация: нет
Всего: 2



в дельфях же есть деректива overload

сделай так
procedure DoIt(A:Byte); overload;
begin
//------//
end;
procedure DoIt(A:Word); overload;
begin
//------//
end;
procedure DoIt(A:Integer;); overload;
begin
//------//
end;
и т.д.
только вот пидётся каждый раз переписывать..



--------------------
кодер + лодырь = колдырь
PM MAIL ICQ Skype GTalk   Вверх
Pakshin A. S.
Дата 25.12.2003, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



А создание нескольких объектов наследующех друг друга с применением виртуальных процедур не поможет?
PM   Вверх
Петрович
Дата 25.12.2003, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 25
Всего: 55



p0s0l
Цитата
type
TSomeData = packed record
  case integer of
    0 : (ValueByte : Byte);
    1 : (ValueWord : Word);
    2 : (ValueDWord : DWord);
    3 : (ValueSingle : Single);
    4 : (ValueDouble : Double);
end;

TElement = packed record
  Data : TSomeData;
  DataType : byte;
end;

Вообще-то можно проще:
Код
type
TSomeData = packed record
  case DataType :integer of
    0 : (ValueByte : Byte);
    1 : (ValueWord : Word);
    2 : (ValueDWord : DWord);
    3 : (ValueSingle : Single);
    4 : (ValueDouble : Double);
end;

Соответственно тогда:
Цитата
// Пример как использовать:

var
El : TSomeData;
...
begin
...
case El.DataType of
  0 : PrintThis(El.ValueByte);
  1 : PrintThis(El.ValueWord);
  2 : PrintThis(El.ValueDWord);
  3 : PrintThis(El.ValueSingle);
  4 : PrintThis(El.ValueDouble);
end;
end;



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Belij
Дата 26.12.2003, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 19.12.2003

Репутация: нет
Всего: нет



да, все это хорошо, но только это значит что при вводе элемента я должен указавать какой тип я счас подразумеваю?
проясню немного ситуацию, очередь у меня не совсем обчная-это очередь на базе гибридного списка, т.е. очередь хранит указатели на данные, элементы очереди индексированы. Я состряпал два объекта (получилось мудрено, но работает). Вот как они выглядят :

{ TDynamicList - класс динамических списков указателей. Для хранения указателей
используется блок памяти, выделенный на куче (список использует менеджер кучи
Windows). Размер блока увеличивается при добавлении элементов специальным
образом: метод Grow. Также возможно прямое указание размера памяти для списка:
с помощью свойства Capacity. Свойство Items обеспечивает прямой доступ к
элементам списка. Вставка производится с помощью метода Insert. Можно
напрямую задавать число элементов списка (свойство Count), при этом размер
блока памяти устанавливается минимальным. Если задается большее число
элементов, то они автоматически заполняются нулями. }

PItemPointer = ^Pointer;

TDynamicList = class(TObject)
private
FHeapHandle: Cardinal;//указатель на область памяти каждого элемента очереди
FList: PItemPointer;// указатель на указатель на область памяти,где хранятся данные
FCount: Integer; //переменная для хранения длины очереди
FCapacity: Integer;//переменная для хранения размера элемента очереди
function ItemPointer(Index: Cardinal): PItemPointer;//выставляет указатель на область с данными(по индексу)
protected
procedure Put(Index: Integer; Item: Pointer);//помещает указатель эдемента списка на область с данными
function Get(Index: Integer): Pointer;// получает указатель на данные эл-ты с заданным индексом
procedure SetCount(NewCount: Integer);// устанавливает число эл-ов списка
procedure SetCapacity(NewCapacity: Integer);//устанавдивает размер эл-та списка
procedure Grow; virtual;// увеличивает размер
public
constructor Create(MaxSize: Cardinal);
destructor Destroy; override;
procedure Clear;
function Add(Item: Pointer): Integer; //добавляет элемент в список
procedure Insert(Index: Integer; Item: Pointer);//вставляет новый элемент в очередь
procedure Delete(Index : Integer);
property Count: Integer read FCount write SetCount;//напрямую позволяет задавать число эл-ов списка
property Capacity: Integer read FCapacity write SetCapacity;//размер памяти для списка
property Items[Index: Integer]: Pointer
read Get write Put; default;//Свойство Items обеспечивает прямой доступ к элементам списка
end;

{ TAnyTypeList class }
{для данных}
{ TAnyTypeList - класс списков блоков памяти, выделенных на куче (список
использует менеджер кучи Windows). При добавлении элемента выделяется новый
блок памяти на куче (размер блока >= размер типа AnyType), затем в него
записываются данные типа AnyType. Указатель на этот блок хранится в списке
FItems. Также возможно прямое изменение размеров каждого блока с помощью
свойства Size. Свойство Items обеспечивает прямой доступ к элементам списка.
Вставка производится с помощью метода Insert.
byte, word,longword,single, double
}

AnyType = Variant;
PAnyType = ^AnyType;//указатель на область памяти,где хранятся данные типа variant

TAnyTypeList = class(TObject)
private
FItems: TDynamicList;//переменная,через которую происходит взаимодействие с эл-ми очереди (класс динамического списка)
FHeapHandle: Cardinal;// указатель на всю память
FMaxSize: Cardinal;//макс размер
protected
function GetCount: Integer;// получаем число элементов с списке (от )
function GetItem(Index: Integer): AnyType; //берет указатель на данные
procedure PutItem(Index: Integer; Item: AnyType);// связываем указатель с данным
function GetSize(Index: Integer): Cardinal; //получает размер эл-та по индексу
procedure SetSize(Index: Integer; Size: Cardinal); //устанавливает размер эл-ты по индексу
public
constructor Create(MaxSize: Cardinal);
destructor Destroy; override;
procedure Clear;
function Add(Item: AnyType): Integer;
procedure Insert(Index: Integer; Item: AnyType);
procedure Delete(Index : Integer);
property Count: Integer read GetCount;
property Items[Index: Integer]: AnyType
read GetItem write PutItem; default; // получение прямого доступа к элементу
property Size[Index: Integer]: Cardinal read GetSize write SetSize;
end;

И вот самое главное - как на входе я определю какой-тип данных должен быть соотнесенconfused.gif

PM MAIL   Вверх
Петрович
Дата 26.12.2003, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 25
Всего: 55



Вместо:
Код
AnyType = Variant;

Сделай:
Код

AnyType = packed record
 case DataType :integer of
   0 : (ValueByte : Byte);
   1 : (ValueWord : Word);
   2 : (ValueDWord : DWord);
   3 : (ValueSingle : Single);
   4 : (ValueDouble : Double);
end;

И у твоих объектов не будет проблем.
Кстати, Variant приблизительно так и устроен.
И еще, если будешь использовать в AnyType динамические типы (LongString, WideString, динамические массивы, объекты), то возможно потребуется усовершенствования.



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Belij
Дата 26.12.2003, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 19.12.2003

Репутация: нет
Всего: нет



Допустим,я сделал так как предлагал p0s0l.
Так вот, как тогда в соответсвии с той структурой, что я публишед выше осуществлять ввод элементов в очередьconfused.gif Ведь с косоли у меня идет ввод,а это значит что все читается как стринги..ок, есть StrToIn, StrToWord, ну а как быть с Byte, DWord...подскажите..
вот как я это пытаюсь делать :

write('element to add (0 - byte,1-Word,2-DWord,3-Single,4-Double)');
ReadLn(el);
dataType:=StrToInt(el);
case dataType of
0 : begin
readln(s);// s - это мое число
data.ValueByte := StrTo?...
1 : c Wordом понятно
2 :?
3 :?
4 : StrToReal.....
end;


и еще, как тогда сделать вывод в консоль элементов содержимого списка, когда я юзал Variant я делал так
for i:=0 to ATL.Count -1 do write(ATL[i],' ');
ATL - объект типа TAnyTypeList


Это сообщение отредактировал(а) Belij - 26.12.2003, 13:42
PM MAIL   Вверх
p0s0l
Дата 26.12.2003, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Можно примерно так вводить/выводить:
Код
var
 data : AnyType;
 ATL : TAnyTypeList;
...
write('element to add (0 - byte,1-Word,2-DWord,3-Single,4-Double)');
ReadLn(el);
data.DataType:=StrToInt(el);
write('enter value:');
ReadLn(s);// s - это мое число
case data.DataType of
0 : data.ValueByte := StrToInt(s);
1 : data.ValueWord := StrToInt(s);
2 : data.ValueDWord := StrToInt(s);
// как вариант вместо трех верхних строк:
//0,1,2 : data.ValueDWord := StrToInt(s);
3 : data.ValueSingle := StrToFloat(s);
4 : data.ValueDouble := StrToFloat(s);
end;
...
//Вывод:
for i:=0 to ATL.Count -1 do
begin
case ATL[i].DataType of
0 : write(ATL[i].ValueByte);
1 : write(ATL[i].ValueWord);
2 : write(ATL[i].ValueDWord);
3 : write(ATL[i].ValueSingle);
4 : write(ATL[i].ValueDouble);
end;
end;


Это сообщение отредактировал(а) p0s0l - 26.12.2003, 23:59


--------------------
С уважением, г-н Посол.
PM   Вверх
Петрович
Дата 27.12.2003, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 25
Всего: 55



Если все так как описанно выше у p0s0l то мне так и непонятно чем Variant не прокатил?


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0609 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.