Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Динамический массив структур (record) как свойство класса. [D7, XP]


Страницы:   1 2 3

SingleStranger ©   (2009-02-11 13:19:00) 

Как реализовать?
Меня интересует способ с простым доступом к любому полю структуры.
Что-то типа того:
TRec = record
 field1: integer;
 field2: string;
end;

TSomeClass = class
 private
   FSRec: array of TRec;
   function GetSRec(Index: Integer): TRec;
   procedure SetSRec(Index: Integer; const Value: TRec);
 public
   function SRecAddNew: Integer;
   function SRecAdd(Value: TRec): Integer;
   property SRec[Index: Integer]: TRec read GetSRec write SetSRec;
end;

И доступ, чтобы был простым, примерно так:
var
 i: integer;
 r: TRec;
begin
 r.field1 := 1;
 r.field2 := 'aaa';
 i := SomeClass.SRecAdd(r);
 SomeClass.SRec[i].field2 := 'bbb';
end;

или как-то так:
var
 i: integer;
begin
 i := SomeClass.SRecAddNew();
 SomeClass.SRec[i].field2 := 'bbb';
end;


Ega23   (2009-02-11 14:20:00) [41]


> А проще не получится?


Вот проще (сугубо ИМХО):

unit Unit2;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, Contnrs;

type

 TSomeClass = class (TObject)
 private
  FField1 : Integer;
   FField2: string;
 public
  procedure Assign(source : TSomeClass);
  property Field1 : Integer read FField1 write FField1;
  property Field2 : string read FField2 write FField2;
 end;

TSomeClassContainer = class (TObject)
 private
   FItems : TObjectList;
   function GetCount: Integer;
   function GetItem(Index: Integer): TSomeClass;
   procedure SetItem(Index: Integer; const Value: TSomeClass);
 public
   constructor Create;
   destructor Destroy; override;

   function AddItem(Item : TSomeClass) : Integer;
   procedure DeleteItem(Index : Integer);
   procedure Clear;

   property Items[Index : Integer] : TSomeClass read GetItem write SetItem;
   property Count : Integer read GetCount;

 end;

implementation

{ TSomeClass }

procedure TSomeClass.Assign(source: TSomeClass);
begin
 FField1 := source.FField1;
 FField2 := source.FField2;
end;

{ TSomeClassContainer }

function TSomeClassContainer.AddItem(Item: TSomeClass): Integer;
begin
 Result := FItems.Add(Item);
end;

procedure TSomeClassContainer.Clear;
begin
 FItems.Clear;
end;

constructor TSomeClassContainer.Create;
begin
 FItems := TObjectList.Create(True);
end;

procedure TSomeClassContainer.DeleteItem(Index: Integer);
begin
 FItems.Delete(Index);
end;

destructor TSomeClassContainer.Destroy;
begin
 FItems.Free;
 inherited;
end;

function TSomeClassContainer.GetCount: Integer;
begin
 Result := FItems.Count;
end;

function TSomeClassContainer.GetItem(Index: Integer): TSomeClass;
begin
 try
   Result := TSomeClass(FItems.Items[i]);
 except
   Result := nil;
 end;
end;

procedure TSomeClassContainer.SetItem(Index: Integer;
 const Value: TSomeClass);
begin
 TSomeClass(FItems.Items[Index]).Assign(Value);
end;

end.


В данном варианте контейнер спрятан в private и доступ к нему идёт через public-функции.


SingleStranger   (2009-02-11 14:10:00) [42]


> Anatoly Podgoretsky ©   (11.02.09 14:01) [10]
> Проще вариант со свойствами.

Это как? Массив свойств?

> Anatoly Podgoretsky ©   (11.02.09 14:00) [9]
> тогда сделай функции присвоения и вызывай их.

Если это единственный способ, то видимо придется. Хотя, если честно, мне он не нравится.

> Ega23 ©   (11.02.09 13:55) [6]
> ... я бы TRec сделал классом, а в TSomeClass
> либо TObjectList в привате организовал с методами доступа ...

Обдумывал и этот вариант, но как-то не хотелось городить класс для, вобщем-то, простой структуры. Это просто настроечная структура, там куча полей простого типа. Но может и над классом подумаю.

Есть еще варианты?


Anatoly Podgoretsky   (2009-02-11 14:01:00) [43]

> SingleStranger  (11.02.2009 13:55:08)  [8]

Проще вариант со свойствами.


Anatoly Podgoretsky   (2009-02-11 14:00:00) [44]

> SingleStranger  (11.02.2009 13:55:07)  [7]

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


SingleStranger   (2009-02-11 13:55:00) [45]


> Anatoly Podgoretsky ©   (11.02.09 13:48) [5]
> > SingleStranger  (11.02.2009 13:19:00)  [0]У тебя нет свойства
> SomeClass.SRec[i].field2Или делай свойство или копируй во
> временную переменную.

Т.е.?
var
i: integer;
r: TRec;
begin
 i := 0;
 r := SomeClass.SRec[i];
 r.field2 := 'bbb';
 SomeClass.SRec[i] := r;
end;

Так? Это еже неудобно.

А проще не получится?


SingleStranger   (2009-02-11 13:55:00) [46]


> Anatoly Podgoretsky ©   (11.02.09 13:48) [5]
> > SingleStranger  (11.02.2009 13:19:00)  [0]У тебя нет свойства
> SomeClass.SRec[i].field2Или делай свойство или копируй во
> временную переменную.

Т.е.?
var
i: integer;
r: TRec;
begin
 i := 0;
 r := SomeClass.SRec[i];
 r.field2 := 'bbb';
 SomeClass.SRec[i] := r;
end;

Так? Это еже неудобно.

А проще не получится?


Ega23   (2009-02-11 13:55:00) [47]

Если честно, то я бы TRec сделал классом, а в TSomeClass либо TObjectList в привате организовал с методами доступа, либо сам TSomeClass от TObjectList унаследовал (это уже от логики зависит).


Anatoly Podgoretsky   (2009-02-11 13:48:00) [48]

> SingleStranger  (11.02.2009 13:19:00)  [0]

У тебя нет свойства SomeClass.SRec[i].field2
Или делай свойство или копируй во временную переменную.


SingleStranger   (2009-02-11 13:46:00) [49]


> SingleStranger   (11.02.09 13:43) [2]
> Помоему, "Left side cannot be assigned to"

При доступе к полю структуры.


Ega23   (2009-02-11 13:44:00) [50]


TSomeClass = class
private
  FSRec: array of TRec;
  function GetSRec(Index: Integer): TRec;
  procedure SetSRec(Index: Integer; const Value: TRec);
public
  function SRecAdd(Value: TRec): Integer;
  property SRec[Index: Integer]: TRec read GetSRec write SetSRec;
end;

function TSomeClass.GetSRec(Index: Integer): TRec;
begin
 Result := FSRec[Index];
end;

procedure TSomeClass.SetSRec(Index: Integer; const Value: TRec);
begin
 FSRec[Index].field1 := Value.field1;
 FSRec[Index].field2 := Value.field2;
end;

function TSomeClass.SRecAdd(Value: TRec): Integer;
begin
 SetLength(FSRec, Hight(FSRec) + 1);
 SetSRec(Hight(FSRec), Value);
 Result := Hight(FSRec);
end;


Что-то типа этого.
P.S. С динамическими массивами практически не работал, поэтому не уверен, как правильно отработает
procedure TSomeClass.SetSRec(Index: Integer; const Value: TRec);
begin
 FSRec[Index].field1 := Value.field1;
 FSRec[Index].field2 := Value.field2;
end;

Возможно достаточно FSRec[Index] := Value;
Надо проверять.


SingleStranger   (2009-02-11 13:43:00) [51]


> clickmaker ©   (11.02.09 13:39) [1]
> и в чем проблема?

Помоему, "Left side cannot be assigned to", если не ошибаюсь. Я код-то переписал, но нынешний вариант, вообще не устраивает. Вот и решил спросить.


clickmaker   (2009-02-11 13:39:00) [52]

и в чем проблема?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо