Как правильно освободить массив объектов класса?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: Как правильно освободить массив объектов класса?

Сообщение Brainenjii » 09.01.2012 22:38:54

Не, мой кодогенератор не страшный, а очень даже милый ^_^
Это когда описываешь файлик
Код: Выделить всё
Pea {
  ID: 1;
  Caption: SubPattern;
  PluralCaption: SubPatterns;
  ModelTemplate: treemodel.ppp;
  Fields: [
    {
      Caption: ShortCaption;
      SQLCaption: SHORT_CAPTION;
      Kind: String;
    },{
      Caption: Caption;
      SQLCaption: CAPTION;
      Kind: String;
    },{
      Caption: Amount;
      SQLCaption: AMOUNT;
      Kind: Integer;
    },{
      Caption: Price;
      SQLCaption: PRICE;
      Kind: Double;
    }
  ];
};

Pea {
  ID: 2;
  Caption: MultiPattern;
  PluralCaption: MultiPatterns;
  ModelTemplate: plainmodel.ppp;
  Fields: [
    {
      Caption: ShortCaption;
      SQLCaption: SHORT_CAPTION;
      Kind: String;
    },{
      Caption: Caption;
      SQLCaption: CAPTION;
      Kind: String;
    },{
      Caption: Amount;
      SQLCaption: AMOUNT;
      Kind: Integer;
    },{
      Caption: Price;
      SQLCaption: PRICE;
      Kind: Double;
    }
  ];
};

Pea {
  ID: 3;
  Caption: Pattern;
  PluralCaption: Patterns;
  ModelTemplate: treemodel.ppp;
  Fields: [
    {
      Caption: ShortCaption;
      SQLCaption: SHORT_CAPTION;
      Kind: String;
    },{
      Caption: Caption;
      SQLCaption: CAPTION;
      Kind: String;
    },{
      Caption: Amount;
      SQLCaption: AMOUNT;
      Kind: Integer;
    },{
      Caption: Price;
      SQLCaption: PRICE;
      Kind: Double;
    },{
      Caption: SubPattern;
      SQLCaption: SUB_PATTERNS;
      Kind: Pea;
      Pea: SubPattern;
    },{
      Caption: SubPattern;
      SQLCaption: SUB_PATTERNS;
      Kind: Pea;
      Pea: SubPattern;
    }
  ];
};

А он тебе из них генерирует несколько файлов - модели, контроллеры, константы, например:
Код: Выделить всё

Unit BPatternUnit;

{$mode objfpc}{$H+}

Interface

Uses
  sysutils, Classes, BCommonUnit, BListsUnit, BObjectUnit, BTreeObjectUnit,
    BQueryUnit, BSQLUnit
//@UsesStart
  , BSubPatternUnit, BMultiPatternUnit
//@UsesStop
;

Type BPatternClass = Class;

Type BPatternsList = Specialize BList<BPatternClass>;
Type BPatternsThreadList =
  Specialize BThreadList<BPatternClass>;

Type BPatternsLinkedList = Specialize BLinkedList<BPatternClass>;
Type BPatternsLinkedThreadList =
  Specialize BLinkedThreadList<BPatternClass>;

Type IPatternInterface = Specialize IGenericInterface<BPatternClass>;
Type BPatternBlank = Specialize BTreeObject<BPatternClass>;

Type

  { BPatternClass }

  BPatternClass = Class(BPatternBlank, IPatternInterface)
    Private
      //@PropertiesPrivateStart
      bShortCaption: String;
      bCaption: String;
      bAmount: Integer;
      bPrice: Double;
      bSubPattern: BSubPatternClass;
      bMultiPatterns: BMultiPatternsThreadList;
      //@PropertiesPrivateStop
      Procedure Load(Const aObject: BPatternClass);
      Procedure InitializeObjects;
    Public
      //@PropertiesPublicStart
      Property ShortCaption: String Read bShortCaption Write bShortCaption;
      Property Caption: String Read bCaption Write bCaption;
      Property Amount: Integer Read bAmount Write bAmount;
      Property Price: Double Read bPrice Write bPrice;
      Property SubPattern: BSubPatternClass Read bSubPattern Write bSubPattern;
      Property MultiPatterns: BMultiPatternsThreadList Read bMultiPatterns Write bMultiPatterns;
      //@PropertiesPublicStop
      Function IsCheap: Boolean;
     
      Function Save(Const aQuery: BQueryClass): Boolean;
      //@InitializeDeclareStart
      Procedure Initialize(Const aShortCaption: String; Const aCaption: String; Const aAmount: Integer; Const aPrice: Double; Const aSubPattern: BSubPatternClass);
      //@InitializeDeclareStop
      Destructor Burn; Override;
End;

Type BPatternsManagerBlank = Specialize BTreeManagerGeneric<BPatternClass>;

Type

  { BPatternsManagerClass }

  BPatternsManagerClass = Class(BPatternsManagerBlank)
    Private
      bPatterns: BPatternsThreadList; Static;
    Public
      Procedure Load;
      Constructor Build;
      Destructor Burn; Override;
End;

Implementation

Const
  SQL_ID = 'ID';
  SQL_DELETED_NOT = 'DELETED = 0';
  SQL_PARENT = 'PARENT';
  SQL_PRIOR = 'PRIOR';
  SQL_NEXT = 'NEXT';
  //@ConstStart
  SQL_NAME = 'PATTERN';
  SQL_TABLE_NAME = 'BPATTERNCLASS';
  SQL_SHORT_CAPTION = 'SHORT_CAPTION';
  SQL_CAPTION = 'CAPTION';
  SQL_AMOUNT = 'AMOUNT';
  SQL_PRICE = 'PRICE';
  SQL_SUB_PATTERNS = 'SUB_PATTERNS';
  SQL_MULTI_PATTERNS = 'MULTI_PATTERNS';
  //@ConstStop

{ BPatternClass }

Procedure BPatternClass.Load(Const aObject: BPatternClass);
Begin
  //@LoadStart
  ShortCaption := aObject.ShortCaption;
  Caption := aObject.Caption;
  Amount := aObject.Amount;
  Price := aObject.Price;
  SubPattern := aObject.SubPattern;
  MultiPatterns.Load(aObject.MultiPatterns.LockList);
  aObject.MultiPatterns.UnlockList;
  //@LoadStop
End;

Procedure BPatternClass.InitializeObjects;
Begin
  If Not(bInitialized) Then
    Begin
      //@InitializeObjectsStart
      bMultiPatterns := BMultiPatternsThreadList.Build;
      //@InitializeObjectsStop
      bInitialized := TRUE;
    End;
End;

Function BPatternClass.IsCheap: Boolean;
Begin
  Result := Price < 10;
End;

Function BPatternClass.Save(Const aQuery: BQueryClass): Boolean;
Var
  aSQL: BSQLClass;
Begin
  aSQL := BSQLClass.Build;
  //@SaveStart
  If ID < 0 Then
    aSQL.Builder.Insert(SQL_TABLE_NAME).AddGenerator.AddParam(SQL_SHORT_CAPTION).AddParam(SQL_CAPTION).AddParam(SQL_AMOUNT).AddParam(SQL_PRICE).AddParam(SQL_SUB_PATTERNS).AddParam(SQL_MULTI_PATTERNS)
  Else
    Begin
      aSQL.Builder.Update(SQL_TABLE_NAME).AddParam(SQL_ID).AddParam(SQL_SHORT_CAPTION).AddParam(SQL_CAPTION).AddParam(SQL_AMOUNT).AddParam(SQL_PRICE).AddParam(SQL_SUB_PATTERNS).AddParam(SQL_MULTI_PATTERNS);
      aSQL.AddParam(SQL_ID, ID);
    End;
 
  aSQL.AddParam(SQL_SHORT_CAPTION, ShortCaption);
  aSQL.AddParam(SQL_CAPTION, Caption);
  aSQL.AddParam(SQL_AMOUNT, Amount);
  aSQL.AddParam(SQL_PRICE, Price);
  If Not(SubPattern = nil) Then aSQL.AddParam(SQL_SUB_PATTERNS, SubPattern.ID)
  Else aSQL.AddParam(SQL_SUB_PATTERNS, -1);
  Result := aQuery.Post(aSQL);
  If Result Then
    Begin
      aSQL.Clear;
  aSQL.Builder.Delete(SQL_TABLE_NAME + '_' + SQL_MULTI_PATTERNS
    End;
  //@SaveStop
  aSQL.Burn;
End;

//@InitializeStart
Procedure BPatternClass.Initialize(Const aShortCaption: String; Const aCaption: String; Const aAmount: Integer; Const aPrice: Double; Const aSubPattern: BSubPatternClass);
Begin
  InitializeObjects;
  bShortCaption := aShortCaption;
  bCaption := aCaption;
  bAmount := aAmount;
  bPrice := aPrice;
  bSubPattern := aSubPattern;
End;
//@InitializeStop

Destructor BPatternClass.Burn;
Begin
  //@BurnStart
  bMultiPatterns.Burn;
  //@BurnStop
End;

{ BPatternsManagerClass }

Procedure BPatternsManagerClass.Load;
Var
  aSQL: BSQLClass;
  aPattern: BPatternClass;
  //@ManagerLoadVarsStart
  aSubPatternsManager: BSubPatternsManagerClass;
  aMultiPatternsManager: BMultiPatternsManagerClass;
  //@ManagerLoadVarsStop
Begin
  EnterState(msLoading);
  aSQL := BSQLClass.Build;
  With BQueryClass.Build(bManager.bDBIndex) Do
    Begin
      aSQL.Builder.Select(SQL_TABLE_NAME).All.
        Where(SQL_DELETED_NOT).OrderBy(SQL_ID);
      Get(aSQL);
      While Not(EOF) Do
        Begin
          //@ManagerLoadStart
          AddObject(ByInteger(SQL_ID), ByInteger(SQL_PARENT),
            ByInteger(SQL_PRIOR), ByInteger(SQL_NEXT)).Initialize(ByString(SQL_SHORT_CAPTION), ByString(SQL_CAPTION), ByInteger(SQL_AMOUNT), ByDouble(SQL_PRICE), aSubPatternsManager.GetObject(ByInteger(SQL_SUB_PATTERNS)));
          //@ManagerLoadStop
          Next;
        End;
      //@ManagerLoadPeasStart
      aSQL.Clear;
      aSQL.Builder.Select(SQL_TABLE_NAME + '_' + SQL_MULTI_PATTERNS).All.
        OrderBy(SQL_NAME);
      Get(aSQL);
      While Not(EOF) Do
        Begin;
          aPattern := GetObject(ByInteger(SQL_NAME));
          aPattern.bMultiPatterns.Add(aMultiPatternsManager.GetObject(ByInteger(SQL_MULTI_PATTERNS)));
          Next;
        End;
      //@ManagerLoadPeasStop
      Burn
    End;
  aSQL.Burn;
  LeaveState;
End;

Constructor BPatternsManagerClass.Build;
Begin
  Inherited Build(bPatterns, 0);
End;

Destructor BPatternsManagerClass.Burn;
Begin
  Inherited Burn;
End;

Initialization
Begin
  BPatternsManagerClass.bPatterns := BPatternsThreadList.Build;
End;

Finalization
Begin
  BPatternsManagerClass.bPatterns.Purge;
  BPatternsManagerClass.bPatterns.Burn;
End;

End.

и так для каждой из Pea'ов
Код: Выделить всё
Unit BMultiPatternUnit;

{$mode objfpc}{$H+}

Interface

Uses
  sysutils, Classes, BCommonUnit, BListsUnit, BObjectUnit, BTreeObjectUnit,
    BQueryUnit, BSQLUnit
//@UsesStart
 
//@UsesStop
;

Type BMultiPatternClass = Class;

Type BMultiPatternsList = Specialize BList<BMultiPatternClass>;
Type BMultiPatternsThreadList =
  Specialize BThreadList<BMultiPatternClass>;

Type BMultiPatternsLinkedList = Specialize BLinkedList<BMultiPatternClass>;
Type BMultiPatternsLinkedThreadList =
  Specialize BLinkedThreadList<BMultiPatternClass>;

Type IMultiPatternInterface = Specialize IGenericInterface<BMultiPatternClass>;
Type BMultiPatternBlank = Specialize BTreeObject<BMultiPatternClass>;

Type

  { BMultiPatternClass }

  BMultiPatternClass = Class(BMultiPatternBlank, IMultiPatternInterface)
    Private
      //@PropertiesPrivateStart
      bShortCaption: String;
      bCaption: String;
      bAmount: Integer;
      bPrice: Double;
      //@PropertiesPrivateStop
      Procedure Load(Const aObject: BMultiPatternClass);
      Procedure InitializeObjects;
    Public
      //@PropertiesPublicStart
      Property ShortCaption: String Read bShortCaption Write bShortCaption;
      Property Caption: String Read bCaption Write bCaption;
      Property Amount: Integer Read bAmount Write bAmount;
      Property Price: Double Read bPrice Write bPrice;
      //@PropertiesPublicStop
     
      Function Save(Const aQuery: BQueryClass): Boolean;
      //@InitializeDeclareStart
      Procedure Initialize(Const aShortCaption: String; Const aCaption: String; Const aAmount: Integer; Const aPrice: Double);
      //@InitializeDeclareStop
      Destructor Burn; Override;
End;

Type BMultiPatternsManagerBlank = Specialize BTreeManagerGeneric<BMultiPatternClass>;

Type

  { BMultiPatternsManagerClass }

  BMultiPatternsManagerClass = Class(BMultiPatternsManagerBlank)
    Private
      bMultiPatterns: BMultiPatternsThreadList; Static;
    Public
      Procedure Load;
      Constructor Build;
      Destructor Burn; Override;
End;

Implementation

Const
  SQL_ID = 'ID';
  SQL_DELETED_NOT = 'DELETED = 0';
  SQL_PARENT = 'PARENT';
  SQL_PRIOR = 'PRIOR';
  SQL_NEXT = 'NEXT';
  //@ConstStart
  SQL_NAME = 'MULTIPATTERN';
  SQL_TABLE_NAME = 'BMULTIPATTERNCLASS';
  SQL_SHORT_CAPTION = 'SHORT_CAPTION';
  SQL_CAPTION = 'CAPTION';
  SQL_AMOUNT = 'AMOUNT';
  SQL_PRICE = 'PRICE';
  //@ConstStop

{ BMultiPatternClass }

Procedure BMultiPatternClass.Load(Const aObject: BMultiPatternClass);
Begin
  //@LoadStart
  ShortCaption := aObject.ShortCaption;
  Caption := aObject.Caption;
  Amount := aObject.Amount;
  Price := aObject.Price;
  //@LoadStop
End;

Procedure BMultiPatternClass.InitializeObjects;
Begin
  If Not(bInitialized) Then
    Begin
      //@InitializeObjectsStart
      //@InitializeObjectsStop
      bInitialized := TRUE;
    End;
End;

Function BMultiPatternClass.Save(Const aQuery: BQueryClass): Boolean;
Var
  aSQL: BSQLClass;
Begin
  aSQL := BSQLClass.Build;
  //@SaveStart
  If ID < 0 Then
    aSQL.Builder.Insert(SQL_TABLE_NAME).AddGenerator.AddParam(SQL_SHORT_CAPTION).AddParam(SQL_CAPTION).AddParam(SQL_AMOUNT).AddParam(SQL_PRICE)
  Else
    Begin
      aSQL.Builder.Update(SQL_TABLE_NAME).AddParam(SQL_ID).AddParam(SQL_SHORT_CAPTION).AddParam(SQL_CAPTION).AddParam(SQL_AMOUNT).AddParam(SQL_PRICE);
      aSQL.AddParam(SQL_ID, ID);
    End;
 
  aSQL.AddParam(SQL_SHORT_CAPTION, ShortCaption);
  aSQL.AddParam(SQL_CAPTION, Caption);
  aSQL.AddParam(SQL_AMOUNT, Amount);
  aSQL.AddParam(SQL_PRICE, Price);
  Result := aQuery.Post(aSQL);
  If Result Then
    Begin
    End;
  //@SaveStop
  aSQL.Burn;
End;

//@InitializeStart
Procedure BMultiPatternClass.Initialize(Const aShortCaption: String; Const aCaption: String; Const aAmount: Integer; Const aPrice: Double);
Begin
  InitializeObjects;
  bShortCaption := aShortCaption;
  bCaption := aCaption;
  bAmount := aAmount;
  bPrice := aPrice;
End;
//@InitializeStop

Destructor BMultiPatternClass.Burn;
Begin
  //@BurnStart
  //@BurnStop
End;

{ BMultiPatternsManagerClass }

Procedure BMultiPatternsManagerClass.Load;
Var
  aSQL: BSQLClass;
  aMultiPattern: BMultiPatternClass;
  //@ManagerLoadVarsStart
  //@ManagerLoadVarsStop
Begin
  EnterState(msLoading);
  aSQL := BSQLClass.Build;
  With BQueryClass.Build(bManager.bDBIndex) Do
    Begin
      aSQL.Builder.Select(SQL_TABLE_NAME).All.
        Where(SQL_DELETED_NOT).OrderBy(SQL_ID);
      Get(aSQL);
      While Not(EOF) Do
        Begin
          //@ManagerLoadStart
          AddObject(ByInteger(SQL_ID), ByInteger(SQL_PARENT),
            ByInteger(SQL_PRIOR), ByInteger(SQL_NEXT)).Initialize(ByString(SQL_SHORT_CAPTION), ByString(SQL_CAPTION), ByInteger(SQL_AMOUNT), ByDouble(SQL_PRICE));
          //@ManagerLoadStop
          Next;
        End;
      //@ManagerLoadPeasStart
      //@ManagerLoadPeasStop
      Burn
    End;
  aSQL.Burn;
  LeaveState;
End;

Constructor BMultiPatternsManagerClass.Build;
Begin
  Inherited Build(bMultiPatterns, 0);
End;

Destructor BMultiPatternsManagerClass.Burn;
Begin
  Inherited Burn;
End;

Initialization
Begin
  BMultiPatternsManagerClass.bMultiPatterns := BMultiPatternsThreadList.Build;
End;

Finalization
Begin
  BMultiPatternsManagerClass.bMultiPatterns.Purge;
  BMultiPatternsManagerClass.bMultiPatterns.Burn;
End;

End.

Плюс, можно описывать файлы не только так, а, скажем, написать что-то вроде:
Код: Выделить всё
Procedure BCodeGenClass.Test;
Var
  aPea: BPeaClass;
Begin
  //ProjectPath := '/home/Brainenjii/Develop/App';
  //InitializePea(0);
  //InitializePea(1);
  //UpdatePea(2);

  aPea := BPeaClass.Build(5, 'Test', 'Tests');
  aPea.AddProperty(BPeaPropertyClass.Build('Name', 'NAME', ppkString));
  InitializePea(aPea);
End;

и получить
Код: Выделить всё
Unit BTestUnit;

{$mode objfpc}{$H+}

Interface

Uses
  sysutils, Classes, BCommonUnit, BListsUnit, BObjectUnit, BTreeObjectUnit,
    BQueryUnit, BSQLUnit
//@UsesStart
 
//@UsesStop
;

Type BTestClass = Class;

Type BTestsList = Specialize BList<BTestClass>;
Type BTestsThreadList =
  Specialize BThreadList<BTestClass>;

Type BTestsLinkedList = Specialize BLinkedList<BTestClass>;
Type BTestsLinkedThreadList =
  Specialize BLinkedThreadList<BTestClass>;

Type ITestInterface = Specialize IGenericInterface<BTestClass>;
Type BTestBlank = Specialize BTreeObject<BTestClass>;

Type

  { BTestClass }

  BTestClass = Class(BTestBlank, ITestInterface)
    Private
      //@PropertiesPrivateStart
      bName: String;
      //@PropertiesPrivateStop
      Procedure Load(Const aObject: BTestClass);
      Procedure InitializeObjects;
    Public
      //@PropertiesPublicStart
      Property Name: String Read bName Write bName;
      //@PropertiesPublicStop
     
      Function Save(Const aQuery: BQueryClass): Boolean;
      //@InitializeDeclareStart
      Procedure Initialize(Const aName: String);
      //@InitializeDeclareStop
      Destructor Burn; Override;
End;

Type BTestsManagerBlank = Specialize BTreeManagerGeneric<BTestClass>;

Type

  { BTestsManagerClass }

  BTestsManagerClass = Class(BTestsManagerBlank)
    Private
      bTests: BTestsThreadList; Static;
    Public
      Procedure Load;
      Constructor Build;
      Destructor Burn; Override;
End;

Implementation

Const
  SQL_ID = 'ID';
  SQL_DELETED_NOT = 'DELETED = 0';
  SQL_PARENT = 'PARENT';
  SQL_PRIOR = 'PRIOR';
  SQL_NEXT = 'NEXT';
  //@ConstStart
  SQL_NAME = 'TEST';
  SQL_TABLE_NAME = 'BTESTCLASS';
  SQL_NAME = 'NAME';
  //@ConstStop

{ BTestClass }

Procedure BTestClass.Load(Const aObject: BTestClass);
Begin
  //@LoadStart
  Name := aObject.Name;
  //@LoadStop
End;

Procedure BTestClass.InitializeObjects;
Begin
  If Not(bInitialized) Then
    Begin
      //@InitializeObjectsStart
      //@InitializeObjectsStop
      bInitialized := TRUE;
    End;
End;

Function BTestClass.Save(Const aQuery: BQueryClass): Boolean;
Var
  aSQL: BSQLClass;
Begin
  aSQL := BSQLClass.Build;
  //@SaveStart
  If ID < 0 Then
    aSQL.Builder.Insert(SQL_TABLE_NAME).AddGenerator.AddParam(SQL_NAME)
  Else
    Begin
      aSQL.Builder.Update(SQL_TABLE_NAME).AddParam(SQL_ID).AddParam(SQL_NAME);
      aSQL.AddParam(SQL_ID, ID);
    End;
 
  aSQL.AddParam(SQL_NAME, Name);
  Result := aQuery.Post(aSQL);
  If Result Then
    Begin
    End;
  //@SaveStop
  aSQL.Burn;
End;

//@InitializeStart
Procedure BTestClass.Initialize(Const aName: String);
Begin
  InitializeObjects;
  bName := aName;
End;
//@InitializeStop

Destructor BTestClass.Burn;
Begin
  //@BurnStart
  //@BurnStop
End;

{ BTestsManagerClass }

Procedure BTestsManagerClass.Load;
Var
  aSQL: BSQLClass;
  aTest: BTestClass;
  //@ManagerLoadVarsStart
  //@ManagerLoadVarsStop
Begin
  EnterState(msLoading);
  aSQL := BSQLClass.Build;
  With BQueryClass.Build(bManager.bDBIndex) Do
    Begin
      aSQL.Builder.Select(SQL_TABLE_NAME).All.
        Where(SQL_DELETED_NOT).OrderBy(SQL_ID);
      Get(aSQL);
      While Not(EOF) Do
        Begin
          //@ManagerLoadStart
          AddObject(ByInteger(SQL_ID), ByInteger(SQL_PARENT),
            ByInteger(SQL_PRIOR), ByInteger(SQL_NEXT)).Initialize(ByString(SQL_NAME));
          //@ManagerLoadStop
          Next;
        End;
      //@ManagerLoadPeasStart
      //@ManagerLoadPeasStop
      Burn
    End;
  aSQL.Burn;
  LeaveState;
End;

Constructor BTestsManagerClass.Build;
Begin
  Inherited Build(bTests, 0);
End;

Destructor BTestsManagerClass.Burn;
Begin
  Inherited Burn;
End;

Initialization
Begin
  BTestsManagerClass.bTests := BTestsThreadList.Build;
End;

Finalization
Begin
  BTestsManagerClass.bTests.Purge;
  BTestsManagerClass.bTests.Burn;
End;

End.
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Как правильно освободить массив объектов класса?

Сообщение leo_bsv » 09.01.2012 22:44:01

офигеть мясо :shock: :!:
Аватара пользователя
leo_bsv
постоялец
 
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола

Re: Как правильно освободить массив объектов класса?

Сообщение alexey38 » 10.01.2012 10:06:48

leo_bsv писал(а):
Код: Выделить всё
Я в таком случае для класса TObjectList делаю наследника с единственным методом типа CItem(Const index:integer):TMyClass; И при необходимости с соответствующим property.

вся фишка в том что я ничего не дописывал а только заменил TObjectList на Specialize TFPGList<TMyObject>; весь код при этом остался рабочим! после чего я затёр прямые преобразования типов вроде
TOdtTableColumnProperties(T.ColsProperties[i])
и код снова остался рабочим... в итоге накладные расходы на использование TFPGList ниже чем при TObjectList (методы практически все те же)... поправьте если не прав.
Дополнительное свойство CItem мне тоже не удобно использовать, т.к. само свойство - массив/список (как хотите обзовите)... и к нему уже должно через индексы обращаться...


Тут дело вкуса и стиля. Можно использовать генерики, можно реализовывать наследование. Кому как нагляднее будет, так и делайте. Я лично не люблю генерики.
А насчет накладных расходов, то если применять inline функции для индексации - CItem, то накладные расходы будут одинаковыми с генериками, т.к. лишнего кода тоже не будет генерироваться.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Как правильно освободить массив объектов класса?

Сообщение leo_bsv » 10.01.2012 13:11:16

alexey38 писал(а):Тут дело вкуса и стиля.

я бы даже сказал - дело случая... в какой-то ситуации наверняка и TObjectList будет оптимальным решением.
Аватара пользователя
leo_bsv
постоялец
 
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола

Re: Как правильно освободить массив объектов класса?

Сообщение alexey38 » 10.01.2012 13:23:14

leo_bsv писал(а):
alexey38 писал(а):Тут дело вкуса и стиля.

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


Я бы сказал все зависит дальнейших планов. Если гарантировано не потребуется новый специфичный функционал, то делать наследование TObjectList не имеет большого смысла, и можно применять генерики.
А вот когда помимо CItem потребуется реализовать какие-нибудь Load, Save и т.п., то в случае генериков придется от них отказываться и создавать новый класс.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Как правильно освободить массив объектов класса?

Сообщение leo_bsv » 11.01.2012 01:02:46

alexey38 писал(а):то в случае генериков придется от них отказываться и создавать новый класс.

т.е. нельзя будет обратиться к методу класса например так:
Код: Выделить всё
MyFPGList[i].MyMethod

:?:
Аватара пользователя
leo_bsv
постоялец
 
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола

Пред.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 248

Рейтинг@Mail.ru