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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> динмические типы, определяемые в процедуре 
V
    Опции темы
stalkerok
Дата 11.12.2008, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Добрый день! как в Delphi передать тип данных в процедуре, например:
есть несколько типов
Код

Type
DotRec = record
 id:integer;
 x:integer;
 y:integer;
 z:integer;
end;

Type
LinkRec = record
 id:integer;
 first:integer;
 last:integer;
end;

Type
NameGridRec = record
 ncell: String[255];
end;

Как в процедуре передать тип?
Код

procedure Load(передать тип);
var
  fileTP: file of ТИП;
  arrTP: ТИП;
begin
................
................
end;

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


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



вижу несколько вариантов:
1. Простой - Написать 3 перегруженных процедуры, каждая из которых работает со своим типом.
2. Более сложный - усложнить структуру. ввести поле "тип данных" и поле-указатель на сами данные, а в процедуре уже разбираться, что пришло.
3. Отказаться от записей и процедур и перейти на ООП.



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
bems
Дата 11.12.2008, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

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



4. Перейти на D2009 и использовать дженерики


--------------------
Обижено школьников: 8
PM MAIL   Вверх
MetalFan
Дата 11.12.2008, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



Цитата(bems @  11.12.2008,  13:34 Найти цитируемый пост)
. Перейти на D2009 и использовать дженерики 

а с дженериками как бы решение выглядело? я просто еще "не перешел" и "не использовал" )))


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
stalkerok
Дата 11.12.2008, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



bems я на 2009, да действительно как бы это выглядело?
PM MAIL   Вверх
bems
Дата 11.12.2008, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

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



ну это зависит от того, что именно нужно )))
например что-то такое
Код

procedure Load<T:record>;
var size:integer;
begin
size:=SizeOf(T);
GetMem(SomeGlobalPointerToLoadedData,size);
SomeGlobalStreamObject.Read(SomeGlobalPointerToLoadedData^,size);
end;

Глобальные переменные тут только потому что у топикстартера это процедура с одним параметром (типом). А вообще можно и что-то такое
Код

procedure Load<T:record>(SomeArg:integer;ArgOfParameterizedType:T;var AnotherArg);


ну и ниже в коде как-то так:
Код

Load<TActualType>(1,VarOfTActualType,someVar)



--------------------
Обижено школьников: 8
PM MAIL   Вверх
stalkerok
Дата 12.12.2008, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



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

типы
Код

Type
DotRec = record
 id:integer;
 x:integer;
 y:integer;
 z:integer;
end;
Type
LinkRec = record
 id:integer;
 first:integer;
 last:integer;
end;
Type
NameGridRec = record
 ncell: String[255];
end;


а вот процедура
Код

procedure SaveArr(FileName: String; Array???:???; typearray:?????);
var
  arrFile: file of typearray????;
  i: integer;
begin
 AssignFile(arrFile, FileName);
 ReWrite(arrFile);
 for i := Low(Array???) to High(Array???) do
  begin
    Write(arrFile, Array???[i]);
  end;
  CloseFile(arrFile);
end;


и затем просто вызывать её
Код

var
  DotArr: array of DotRec;
  LinkArr: array of LinkRec;
  GridNameArr: array of NameGridRec;
.......
procedure SaveArr('txt1', DotArr, DotRec);
procedure SaveArr('txt2', LinkArr, LinkRec);
procedure SaveArr('txt3', GridNameArr, NameGridRec);


Это сообщение отредактировал(а) stalkerok - 12.12.2008, 00:46
PM MAIL   Вверх
stalkerok
Дата 12.12.2008, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Может поможет кто.  smile 
PM MAIL   Вверх
elvis79
Дата 12.12.2008, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 13.11.2008
Где: Украина, Ивано-Фр анковск

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



Array -- это массив записей (array of DotRec, array of LinkRec, array of NameGridRec)

Если я правильно понял, то я б организовал через TObjectList. 
А также создал предка с виртуальными методами и от него породил бы DotRec, LinkRec и NameGridRec. Реализация методов была в каждом предке своя

Код

type
  TFigure = class
  private
  public
    procedure Save; virtual; abstruct;
  end;
  
  TDotRec = class(TFigure)
  private
  public
    procedure Save; 
  end;

  TLinkRec = class(TFigure)
  private
  public
    procedure Save; 
  end;

  
  TMyList = class(TObjectList) // --- список (вместо массива)
  private
  public
    procedure SaveToFile(const AFileName: String); 
    property Items[Index: Integer]: TFigure read GetItems write SetItems;
  end;


Реализация

Код

procedure TMyListSaveToFile(const AFileName: String); 
var
  i: Integer;
begin
  for i := 0 to Count - 1 do
    Items[i].Save;
end;

procedure TDotRec.Save; 
begin
  ShowMessage('I am DotRec');
end;

procedure TLinkRec.Save; 
begin
  ShowMessage('I am LinkRec');
end;


если заинтересует пиши, помогу

PM MAIL WWW ICQ Jabber   Вверх
stalkerok
Дата 14.12.2008, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



elvis79 Спасибо!

Насколько я понял всё равно придётся писать для каждого типа данных свою процедуру и эти процедуры будут одинаковые(в моём случае с сохранением массива в файл) а отличаться будут в процедурах только тип используемых переменных, а если типов данных 10 то писать 10 одинаковых процедур?
Но если использовать дженерики, там только написать одну процедуру, при вызове которой передавать тип данных?

заранее Спасибо!
PM MAIL   Вверх
NewDima
Дата 15.12.2008, 08:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 922
Регистрация: 20.2.2006
Где: <?here?>

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



ну и сумбур
Код

type
MyType1 = record x, y, z: integer; end;
MyType2 = record x, y, z: single; end;
var
 Ar1: MyType1; Ar2: MyType2;
procedure SaveArrToFile(filename: TFileName; arr: pointer; len: integer);
var  i: integer; arrFile: file of byte;
begin
 AssignFile(arrFile, FileName);
 ReWrite(arrFile);
 for i:=0 to len-1 do Write(arrFile, PByteArray(arr)^[i]);
 CloseFile(arrFile);
end;


звать так:
Код

var s: string;
s1: array[1..255] of MyType1;
s2: array[1..255] of MyType2;
i: integer;
begin
s:= 'some string';
for i:=1 to 255 do s1[i].x := 1;
for i:=1 to 255 do s2[i].x := 1.1; 
SaveArrToFile('text string.txt', @s[1], length(s));
SaveArrToFile('int vector.txt',  @s1, 255*sizeof(MyType1));
SaveArrToFile('signle vector.txt',  @s2, 255*sizeof(MyType2));
  { TODO -oUser -cConsole Main : Insert code here }
end.


такой процедуре корми что захочешь, Но мой тебе совет, не используй эти функции:
Код

AssignFile
ReWrite
Write
CloseFile

большие структуры будут долго писаться (пишутся то по байтам), используй CreateFile, WriteFile

Код

function SaveArrToFile(filename: TFileName; arr: pointer; len: integer):boolean;
var  i: integer; arrFile: hfile; wr: Cardinal;
begin
Result:=false;
arrfile := CreateFile(PChar(FileName),
           GENERIC_WRITE,
           FILE_SHARE_READ,
           nil,
           CREATE_ALWAYS,
           FILE_ATTRIBUTE_NORMAL,
           0);
if (arrFile=INVALID_HANDLE_VALUE) then exit;
WriteFile(arrFile, PByteArray(arr)^, len, wr, nil);
FileClose(arrFile);
if (len<>wr) then exit;
Result:=true;
end;

как вишь, никакого цикла, скорость большая, но есть ограничение записываемого буфера.
использование даже изменять не надо


Это сообщение отредактировал(а) NewDima - 17.12.2008, 07:43
PM ICQ   Вверх
MetalFan
Дата 15.12.2008, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



Цитата(NewDima @  15.12.2008,  08:03 Найти цитируемый пост)
Но мой тебе совет, не используй эти функции:

почему? обоснуй!


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
NewDima
Дата 15.12.2008, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 922
Регистрация: 20.2.2006
Где: <?here?>

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



я дальше код привел, еще раз вставить?=)
найди пять различий smile 

а вообще, гибкость и расширенные возможности

Это сообщение отредактировал(а) NewDima - 15.12.2008, 16:17
PM ICQ   Вверх
MetalFan
Дата 16.12.2008, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



NewDima, не вижу преимущества в приведенном коде. кто виноват, что ты объявил типизированный файл в первом варианте?


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
NewDima
Дата 16.12.2008, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 922
Регистрация: 20.2.2006
Где: <?here?>

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



с типизацией файла начал топикстартер.
Код

procedure SaveArrToFile(filename: TFileName; arr: pointer; len: integer);
var  i: integer; arrFile: file;
begin
 AssignFile(arrFile, FileName);
 ReWrite(arrFile, len);
 BlockWrite(arrFile, PByteArray(arr)^[0], 1);
 CloseFile(arrFile);
end;

рады? Я сторонник WinAPI и его гибкости;

Это сообщение отредактировал(а) NewDima - 17.12.2008, 07:50
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.0576 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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