Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2002.12.05;
Скачать: [xml.tar.bz2];

Вниз

Помогите сделать тип данных....   Найти похожие ветки 

 
TankMan   (2002-10-21 00:43) [0]

Эх.. кажется правильно сформулировал вопрос...
я вот мучаюсь, но так и не могу сделать...
Мне нужен тип, вобщем, вроде такого
type TMyType=array of record
Per1,Per2,Per3:TStrings;
end;
Только вот чтобы при описании
Peremennaya:TMyType;
Работать с записью можно было как с типом TStrings
,т.е. Peremennaya.Add(...) ну и соответственно
Peremennaya[0].Per1 или Per2...вот...
Я сколько не парился, ну не получается у меня.. пожалуйста, кому не особо сложно, подскажите как сделать такой тип. Буду очень признателен.


 
Anatoly Podgorestky   (2002-10-21 00:58) [1]

Смутно объясняешь
Peremennaya.Add(...) это только с классами и вроде в Д7 можно
Peremennaya[0].Per1 это ты уже описал, только выделяй место в массиве с помощью SetLength(Peremennaya,N)
Посмотри в хелпе разделы по Record и Dynamic Arrays
Книги тоже не помешают


 
TankMan   (2002-10-21 01:51) [2]

>Peremennaya.Add(...) это только с классами и вроде в Д7 можно
Ну а как-то же реализует это TStrings?


 
TankMan   (2002-10-21 01:54) [3]

А может класс какой переопределить чуток и сделать такой, который нужно? Только вот проблема, я так и не смог разобраться, как сделать так, как сделано в типе TStrings. :(


 
Viktor Kushnir   (2002-10-21 08:38) [4]

Вот кусечек хелпа к Дельфи на тему Array properties

type

TStringArray = class
public
property Strings[Index: Integer]: string ...; default;
...
end;

Ну естественно, что методы SetString И GetString для записи и чтения из массива, тбе надо будет описать самому.


 
TankMan   (2002-10-21 21:24) [5]

Да но как я понимаю это просто массив строк, а мне нужен массив записей, и именно записей с 3 полями TStrings... может я чего недопонимаю?


 
Рыжик   (2002-10-22 12:44) [6]

Типа того:
TRecord = class
public
Per1,Per2,Per3:TStrings;
constructor Create;
destructor Destroy; override;
end;

TMyType = class
private
FItems:array of TRecord;
function GetItems(Index: integer): TRecord;
procedure SetItems(Index: integer; const Value: TRecord);
public
property Items[Index:integer]:TRecord read GetItems write SetItems; default;
procedure Add(Item:TRecord);
procedure Delete(Index:integer);
destructor Destroy; override;
end;

implementation

procedure TMyType.Add(Item: TRecord);
var i:integer;
begin
i:=Length(FItems);
SetLength(FItems,i+1);
FItems[i]:=Item;
end;

procedure TMyType.Delete(Index: integer);
var i:integer;
rec:TRecord;
begin
rec:=FItems[Index];
for i:=Index+1 to High(FItems) do
FItems[i]:=FItems[i-1];
SetLength(FItems,Length(FItems)-1);
rec.Free;
end;

destructor TMyType.Destroy;
var i:integer;
begin
for i:=0 to Length(FItems)-1 do
FItems[i].Free;
inherited;
end;

function TMyType.GetItems(Index: integer): TRecord;
begin
Result:=FItems[Index];
end;

procedure TMyType.SetItems(Index: integer; const Value: TRecord);
begin
FItems[Index]:=Value;
end;

{ TRecord }

constructor TRecord.Create;
begin
inherited;
Per1:=TStringList.Create;
Per2:=TStringList.Create;
Per3:=TStringList.Create;
end;

destructor TRecord.Destroy;
begin
Per1.Free;
Per2.Free;
Per3.Free;
inherited;
end;


Пример:

procedure TForm1.Button1Click(Sender: TObject);
var a:TMyType;
rec:TRecord;
begin
a:=TMyType.Create;
rec:=TRecord.Create;
rec.Per1.Add("tra-la-la");
a.Add(rec);
ShowMessage(a[0].Per1[0]);
a.Free;
end;


 
TankMan   (2002-10-23 10:45) [7]

>>Рыжик
Ооо.. спасибо большое это - то, что мне нужно было... спасибо.


 
Рыжик   (2002-10-23 11:53) [8]

Только будьте внимательны с элементами массива: при добавлении нужно каждый раз(!) создавать новый, а освобождением их занимается TMyType.
Например:
a:=TMyType.Create;
rec:=TRecord.Create;//создали одну "запись"
rec.Per1.Add("1");//добавили одну строку
a.Add(rec);
rec.Clear;
rec.Per1.Add("2");
a.Add(rec);
ShowMessage(a[0].Per1[0]);//выдаст "2", а не "1"
a.Free;//не надо делать Rec.Free;



 
TankMan   (2002-10-23 20:16) [9]

Погоди ка, а почему это так, ведь по идее, во второй раз он должен добавить a[1].Per1[0] а не заменять a[0].per1[0], как тогда добавлять a[1]?
a:=TMyType.Create;
rec:=TRecord.Create;//создали одну "запись"
rec.Per1.Add("1");//добавили одну строку
a.Add(rec);
//rec.free не надо?
rec:=TRecord.Create;
rec.Per1.Add("2");
a.Add(rec);
ShowMessage(a[0].Per1[0]);//выдаст "1", а не "2"?
ShowMessage(a[1].Per1[0]);//выдаст 2?
a.Free;//не надо делать Rec.Free;
Так чтоли?
Ты говоришь, что не надо делать rec.free?
А в каком месте TMyType его освобождает?
Я что-то не пойму?И если так, то почему?



 
Рыжик   (2002-10-24 11:46) [10]

Так, начнём по-порядку:
> а почему это так, ведь по идее, во второй раз он должен
> добавить a[1].Per1[0] а не заменять a[0].per1[0]

Так и происходит, т.е во второй раз добавляется а[1].Per1[0]. Но обрати внимание на то, что TRecord - это "псевдорекорд", который на самом деле является классом! При добавлении в массив класса в действительности добавляется указатель, а не значение (как, например, было бы с каким-нибудь Integer или другим простым типом данных). Получается следующее: мы создали всего один объект TRecord, чего-то с ним сделали, занесли указатель на него в первый элемент массива. Теперь вызываем метод этого же самого(!) объекта, и заносим во второй элемент массива. В результате имеем a[0]=a[1]. Т.е. когда мы делали rec.Clear;
rec.Per1.Add("2"); мы изменили сам объект, на который ссылается a[0]. Поскольку в a[0] находится указатель, а не сам объект, то и
результат ShowMessage(a[0].Per1[0]);//выдаст "2", а не "1"


> как тогда добавлять a[1]?

Именно так, как ты и делаешь в TankMan © (23.10.02 20:16)

> //rec.free не надо?

Нет. Если вызвать rec.Free сразу после добавления его в массив, а потом попытаться обратиться к этому эл-ту массива, то вы увидите, что a[0]=nil и a[0].Per1[0] вызовет ошибку. Уничтожением объекта rec занимается "массив" a.


> Ты говоришь, что не надо делать rec.free?
> А в каком месте TMyType его освобождает?

a.Free вызывает a.Destroy (если a<>nil). Дальше см. реализацию TMyType.Destroy:
destructor TMyType.Destroy;
var i:integer;
begin
for i:=0 to Length(FItems)-1 do
FItems[i].Free;
inherited;
end

Ну так вот. После всего вышесказанного, я советую разобраться, как всё это действует, а потом написать самостоятельно то, что требовалось. Очень полезно для развития ;)



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2002.12.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.009 c
14-14799
RV
2002-11-15 09:18
2002.12.05
Мысля


3-14388
VAleksey
2002-11-14 10:45
2002.12.05
Проблемы при выполнения запроса


14-14742
Николай Быков
2002-11-13 16:58
2002.12.05
Прямоугольники


1-14494
Vit@ly
2002-11-26 09:17
2002.12.05
Как поместить ComboBox на заголовок формы?


1-14605
3asys
2002-11-22 10:07
2002.12.05
Кодировка в TRichEdit в run-time





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