Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.10;
Скачать: CL | DM;

Вниз

Подскажите, как правильно работать со свойствами-массивами   Найти похожие ветки 

 
Константинов ©   (2004-09-23 01:31) [0]

Что-то не очень получается. Выкручиваюсь например так:

MyClass = class ( TPersistent )
private
FList : TList;
public
propertyItems[Index: integer] : TMyObject read GetItem write SetItem;
function Add ( Item : TMyObject ) : integer;
procedure Delete ( Index : integer );
...
//вызов функции Add
var A : TMyClass;
   B : TMyObject;
begin
 A := TMyClass.Create;
 B := TMyObject.Create;
 A.Add(B);
end;

function Add ( Item : TMyObject ) : integer;
var P : ^TMyObject;
begin
GetMem(P,SizeOf(TMyObject));  
 P^ := Item;
 Result := FList.Add(P);
end;

procedure Delete ( Index : integer );
var P : ^TMyObject;
begin
 P := FList[Index];
 P^.Free;
 FList.Delete(Index);
end;

function GetItems ( Index : integer ) : TMyObject;
var P : ^TMyObject;
begin
 P := FList[Index];
 Result := P^;
end;

и т.д. и т.п. эх руки мои кривые...
аш самому глядеть не хочется на такой код.
полез в дебри VCL посмотреть как там это сделано. Нарыл, что используют еще один класс (например TMemoStrings для хранения строк ) и как-то через SendMessage выделяют память под строку где-то в недрах компонента.
Или ( для Font, Pen и т.д. используют TResourceManager, который чрезвычайто замысловато вызывает тот же GetMem

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

Если можно, самый примитивный примерчик, как корректно реализовать сабж, а то я уже не знаю, где может произойти утечка памяти ( например из-за возникновения исключения не будет вызван Free )

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


 
Defunct ©   (2004-09-23 02:15) [1]

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

не совсем понял ваш вопрос, т.е. не понимаю зачем там GetMem и т.п. Посмотрите может поможет такая реализация:

TSignal = class(TDataControl)
Private
 FSignals    : Array of TSignal;
 ...
Protected
 ...
 Function  GetItem(Index: Integer): TSignal;Virtual;
 Procedure SetItem(Index: Integer; Value: TSignal);Virtual;
 ...
Public
 Property    Items[Index: Integer]: TSignal read GetItem write SetItem;
 Property    Count:Integer Read GetCount Write SetCount;
 ...
 Function    Add:TSignal;Virtual;Abstract;
End;

Procedure TSignal.SetItem;
Begin
 Try
   FSignals[Index] := Value;
 Except
   ShowMessage("Wrong index: "+Int2String(Index));
 End;
End;

Function TSignal.GetItem;
Begin
 Try
   Result := FSignals[Index];
 Except
   ShowMessage("Wrong index: "+Int2String(Index));
 End;
End;

Function TSignalGroup.Add;
Begin
 Case ObjectMap.ObjectID Of
   gt_Abstract: FItem := CreateSignal;
   gt_Discrete: FItem := CreateDiscreteSignal;
   gt_Analog:   FItem := CreateAnalogSignal;
   gt_Counter:  FItem := CreateAnalogSignal;
   gt_Control:  FItem := CreateControlSignal;
   Else FItem := CreateSignal;
 End;
 Count := Count + 1;
 SetLength(FSignals, Count);
 FSignals[Count-1] := FItem;
 Result := FItem;
End;


Т.е. как в TList просто выполнять постоянное увеличение числа элементов.


 
Defunct ©   (2004-09-23 02:19) [2]

FItem задан в классе, в котором впервые появляется реализация абстрактного метода Add.

в приведенном примере
FItem : TSignal;


 
Fedia   (2004-09-23 03:00) [3]

В этом примере свойство-массив основано на переменной динамического массива строк.
 
 ArUserName = array of String;

 TClassWithArray = class
 private
   function GetUserName(const MIndex: Integer): String;
   procedure AddUser(const User: String);
   procedure DeleteUser(const User: String);
 public
   UsersNames: ArUserName;
   Property UserName[const MIndex: Integer]: String read GetUserName;
 end;

implementation

function TClassWithArray.GetUserName(const MIndex: Integer): String;
begin
 if (MIndex>=0) and (MIndex<=High(UsersNames)) then
 Result:=UsersNames[MIndex] else
 Result:="Юзера с таким номером не существует";
end;

procedure TClassWithArray.AddUser(const User: String);
var
 i: integer;
begin
 i:=Length(UsersNames);
 SetLength(UsersNames, i+1);
 UsersNames[i]:=User;
end;

procedure TClassWithArray.DeleteUser(const User: String);
var
 ar: ArUserName;
 i, m: Integer;
begin
 for i:=0 to High(UsersNames) do
 if AnsiLowerCase(UsersNames[i])<>AnsiLowerCase(User) then
 begin
   m:=Length(ar);
   SetLength(ar, m+1);
   ar[m]:=UsersNames[i];
 end;
 UsersNames:=ar;
 ar:=nil;
end;


 
jack128 ©   (2004-09-23 03:27) [4]

У-у-у. Ну ты намутил :-))

uses
 contnrs;

type
 TMyClass = class(TObject);
 TMyClassList = class(TObjectList)
 protected
   function GetItem(Index: Integer): TMyClass;
   procedure SetItem(Index: Integer; AObject: TMyClass);
 public
   function Add(AObject: TMyClass): Integer;
   function Remove(AObject: TMyClass): Integer;
   function IndexOf(AObject: TMyClass): Integer;
   procedure Insert(Index: Integer; AObject: TMyClass);
   property Items[Index: Integer]: TMyClass read GetItem write SetItem; default;
 end;
Реализация каждого метода - это просто вызов унаследованного..
Наример

function TMyClassList.Add(AObject: TMyClass): Integer;
begin
 Result:= inherited Add(AObject);
end;
или
function TMyClassList.GetItem(Index: Integer): TMyClass;
begin
 Result := inherited Items[Index] as TMyClass;
end;
В принципе, если те нужно ограничить интерфейс своего списка по сравнению TObjectList (например не допускать вставки элемента) можно и так как ты. Но тогда тоже все очень просто, что то типа этого

function Add ( Item : TMyObject ) : integer;
begin
 Result := FList.Add(P);
end;

procedure Delete ( Index : integer );
begin
// P^.Free; при использовании TObjectList с OwnsObjects = True объекты при удалении сами уничтажаются..
FList.Delete(Index);
end;

Так что все очень просто.


 
Константинов ©   (2004-09-23 17:37) [5]

Громадное спасибо!
Я первый раз слышу о существовании класса TObjectList.
Буду пробовать! :)



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

Текущий архив: 2004.10.10;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.026 c
4-1094532736
Duka
2004-09-07 08:52
2004.10.10
USB


14-1095670737
Rule
2004-09-20 12:58
2004.10.10
Неужели в москве такие зарплаты ????


1-1095718048
VAmpiro$
2004-09-21 02:07
2004.10.10
Как записать в файл рисунок?


3-1095263457
Surrender
2004-09-15 19:50
2004.10.10
DateTime в формате String в базе Access


14-1095933019
Lexxx
2004-09-23 13:50
2004.10.10
Помогите найти компонент.