Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2003-07

TCollection question

12 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

James Mills

Is there an example of using TCollection or something (without having to write the code myself) that manages a collection of FPC style classes (objects) ?

I'd like to see one, code I have written to handle a dynamic array of objects has gone out of control... (Using FPC classes here)

cheers
James

- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

Marco van de Voort
to James Mills
Show quoted text 6 lines
Is there an example of using TCollection or something (without having to write the code myself) that manages a collection of FPC style classes (objects) ? I'd like to see one, code I have written to handle a dynamic array of objects has gone out of control... (Using FPC classes here)

IIRC, TCollection only stores TCollectionItem derived classes.

TList is closer to what you want probably.

Reply by email

James Mills
to Marco van de Voort
Marco van de Voort wrote 10 lines
> Is there an example of using TCollection or something (without having to > write the code myself) that manages a collection of FPC style classes > (objects) ? > > I'd like to see one, code I have written to handle a dynamic array of > objects has gone out of control... (Using FPC classes here) IIRC, TCollection only stores TCollectionItem derived classes. TList is closer to what you want probably.

Is there an example other than list.pp in the fcl source ?

Also just for the record of knowing... I have attached datanicks.pas which hold a dynamic array of TNick ... Is this what TList already does (if so I'm wasting my time writing my own code...) ?

cheers
James

_______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

Marco van de Voort
to James Mills
Show quoted text 9 lines
> IIRC, TCollection only stores TCollectionItem derived classes. > > TList is closer to what you want probably. Is there an example other than list.pp in the fcl source ? Also just for the record of knowing... I have attached datanicks.pas which hold a dynamic array of TNick ... Is this what TList already does (if so I'm wasting my time writing my own code...) ?

Pretty much yes, but in a class wrapper. You can add and remove items, iterate through them etc. Maybe you can derive a class from TList to customize it a bit.

There are two things to think of:
- you yourself have to make sure that elements are properly freed, so when deleting object A, get a reference to it, delete it from the list, and then free the object. (however that can be automized in the class warpper)
- The internal list has two counters, instead of just "nNicks". One (capacity) is the reserved space, the other (count) is the amount of elements filled. This avoids too many memory fragmenting reallocs. (but that's better, not worse)

I learned to use the classes from code snippets written for Delphi.

There is FCL documentation somewhere (and it will be in the next full release), but I couldn't find a recent version so fast.

So I put down a very old version (April 2002) on the web here:

www.stack.nl/~marcov/fcl.pdf

it at least describes the tlist methods.

Reply by email

James Mills
to Marco van de Voort
Marco van de Voort wrote 13 lines
> > IIRC, TCollection only stores TCollectionItem derived classes. > > > > TList is closer to what you want probably. > > Is there an example other than list.pp in the fcl source ? > > Also just for the record of knowing... I have attached datanicks.pas > which hold a dynamic array of TNick ... Is this what TList already does > (if so I'm wasting my time writing my own code...) ? Pretty much yes, but in a class wrapper. You can add and remove items, iterate through them etc. Maybe you can derive a class from TList to customize it a bit.

However TList by itself would work though ?

Show quoted text 6 lines
There are two things to think of: - you yourself have to make sure that elements are properly freed, so when deleting object A, get a reference to it, delete it from the list, and then free the object. (however that can be automized in the class warpper)

Is this all done and automated in TList ?

Show quoted text 13 lines
- The internal list has two counters, instead of just "nNicks". One (capacity) is the reserved space, the other (count) is the amount of elements filled. This avoids too many memory fragmenting reallocs. (but that's better, not worse) I learned to use the classes from code snippets written for Delphi. There is FCL documentation somewhere (and it will be in the next full release), but I couldn't find a recent version so fast. So I put down a very old version (April 2002) on the web here: www.stack.nl/~marcov/fcl.pdf

I think it's here also in html format:
http://www.nl.freepascal.org/docs-html/fcl/classes/tlist.html

cheers
James

Show quoted text 6 lines
it at least describes the tlist methods. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

Marco van de Voort
to James Mills
Show quoted text 9 lines
On Sun, Jul 06, 2003 at 05:11:17PM +0200, Marco van de Voort wrote: > > which hold a dynamic array of TNick ... Is this what TList already does > > (if so I'm wasting my time writing my own code...) ? > > Pretty much yes, but in a class wrapper. You can add and remove items, > iterate through them etc. Maybe you can derive a class from TList to > customize it a bit. However TList by itself would work though ?

Basically yes. But derive it anyway, in case you want to extend it later.

Show quoted text 5 lines
> - you yourself have to make sure that elements are properly freed, so > when deleting object A, get a reference to it, delete it from the list, > and then free the object. (however that can be automized in the class > warpper) Is this all done and automated in TList ?

No. So you have to that yourself. This because TList can also store pointers to records, which don't have to be finalised. So deallocation is still manual.

But it is trivial. Assume you want to delete entry 3, assuming that variable TheList is the TList:

var t : MyObjectType

t:=MyObjectType(TheList[3]);
TheList.delete(3);
t.free;

You can solve it like this: (untested)

type tmyTList = class TList
		  public
	            procedure DeleteCompletely(index :Integer);
		  end;
procedure tmyTList.DeleteCompletely(index: Integer);
var t : MyObjecType;
begin
  t:=MyObjectType(Items[3]);
  delete(3);
  if tNIL
   t.free;
end;

See TList as a versatile baseclass to quickly build a dedicated, very easy to use container on top of.

Show quoted text 9 lines
> There is FCL documentation somewhere (and it will be in the next full > release), but I couldn't find a recent version so fast. > > So I put down a very old version (April 2002) on the web here: > > www.stack.nl/~marcov/fcl.pdf I think it's here also in html format: http://www.nl.freepascal.org/docs-html/fcl/classes/tlist.html

That's the place I meant yes.

Reply by email

James Mills
to Marco van de Voort
Marco van de Voort wrote 11 lines
> On Sun, Jul 06, 2003 at 05:11:17PM +0200, Marco van de Voort wrote: > > > which hold a dynamic array of TNick ... Is this what TList already does > > > (if so I'm wasting my time writing my own code...) ? > > > > Pretty much yes, but in a class wrapper. You can add and remove items, > > iterate through them etc. Maybe you can derive a class from TList to > > customize it a bit. > > However TList by itself would work though ? Basically yes. But derive it anyway, in case you want to extend it later.

In this case then as I've both read your replies and the webpage about TList I shall extend it :) That'll probably be the best option. Right ?

Thanks for your prompt help, I dunno why I'm coding at 0140 in the bloody morning but anyway :)

cheers
James

Show quoted text 56 lines
> > - you yourself have to make sure that elements are properly freed, so > > when deleting object A, get a reference to it, delete it from the list, > > and then free the object. (however that can be automized in the class > > warpper) > Is this all done and automated in TList ? No. So you have to that yourself. This because TList can also store pointers to records, which don't have to be finalised. So deallocation is still manual. But it is trivial. Assume you want to delete entry 3, assuming that variable TheList is the TList: var t : MyObjectType t:=MyObjectType(TheList[3]); TheList.delete(3); t.free; You can solve it like this: (untested) type tmyTList = class TList public procedure DeleteCompletely(index :Integer); end; procedure tmyTList.DeleteCompletely(index: Integer); var t : MyObjecType; begin t:=MyObjectType(Items[3]); delete(3); if tNIL t.free; end; See TList as a versatile baseclass to quickly build a dedicated, very easy to use container on top of. > > There is FCL documentation somewhere (and it will be in the next full > > release), but I couldn't find a recent version so fast. > > > > So I put down a very old version (April 2002) on the web here: > > > > www.stack.nl/~marcov/fcl.pdf > > I think it's here also in html format: > http://www.nl.freepascal.org/docs-html/fcl/classes/tlist.html That's the place I meant yes. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

Matt and Lisa Emson
to James Mills

Why not use a TObjectList?? IIRC that is available. In unit Contnrs.pas. It will do a lot more for you. It can 'own' the objects, and therefore free you from needing to manage them.

Simple descendent (typed at speed, with no testing):

N.B. This is a WRAPPER because it allows the programmer more control over the interface to the class. However a descendent would work the same way pretty much. You'd probably just alter the 'Add' to 'AddXXX' so as to not clash with 'Add' from TList. Otherwise you would hide the method and make in unavailable. This wrapper is really usefull... I use this basic design all the time!!

TMyListItemClass = class; {your class to store}

TMyList = class
private
  FList: TList;
protected
  procedure SetItem( Index: integer; Value: TMyListItemClass);
  function GetItem(Index: integer): TMyListItemClass;
public
  Constructor Create; virtual;
  Destructor Destroy; override;
  function Add(AItem: TMyListItemClass): integer;
  procedure Delete( AIndex: integer );
  function Count: integer;
  property Items[Index: integer]: TMyListItemClass read GetItem write
SetItem;
end;
 procedure SetItem( Index: integer; Value: TMyListItemClass);
 begin
  FList[Index] := Value;
 end;
  function GetItem(Index: integer): TMyListItemClass;
  begin
    Result := TMyListItemClass(FList[Index] );
  end;
  Constructor Create; virtual;
  begin
    FList := TList.Create;
  end;
  Destructor Destroy; override;
  begin
     {don't forget some code to empty list....!!!!}
     FList.Free;
    inherited;
  end;
  function Add(AItem: TMyListItemClass): integer;
  begin
    result := FList.Add(AItem);
end;
procedure Delete( AIndex: integer );
begin
  FList.Delete(AIndex);
end;
  function Count: integer;
  begin
     Result := FList.Count;
  end;
Earlier message 21 lines
----- Original Message ----- From: "James Mills" To: Sent: Sunday, July 06, 2003 4:56 PM Subject: Re: [fpc-pascal]TCollection question > Actually Michael, > > Could you possibly spare 5 mins and give a really simple example of a > TList descandent ? I'm a tad confused here, (too slowly getting > anywhere)... > > Thank you :) > > cheers > James > > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

James Mills
to Matt and Lisa Emson
Matt and Lisa Emson wrote 12 lines
Why not use a TObjectList?? IIRC that is available. In unit Contnrs.pas. It will do a lot more for you. It can 'own' the objects, and therefore free you from needing to manage them. Simple descendent (typed at speed, with no testing): N.B. This is a WRAPPER because it allows the programmer more control over the interface to the class. However a descendent would work the same way pretty much. You'd probably just alter the 'Add' to 'AddXXX' so as to not clash with 'Add' from TList. Otherwise you would hide the method and make in unavailable. This wrapper is really usefull... I use this basic design all the time!!

Thank you for this. I was a tad confused as my original idea was wrong in that I tried to create a pure descandent of TList and extend it...

I will use your basic design below, thank you :)

cheers
James

Show quoted text 86 lines
TMyListItemClass = class; {your class to store} TMyList = class private FList: TList; protected procedure SetItem( Index: integer; Value: TMyListItemClass); function GetItem(Index: integer): TMyListItemClass; public Constructor Create; virtual; Destructor Destroy; override; function Add(AItem: TMyListItemClass): integer; procedure Delete( AIndex: integer ); function Count: integer; property Items[Index: integer]: TMyListItemClass read GetItem write SetItem; end; procedure SetItem( Index: integer; Value: TMyListItemClass); begin FList[Index] := Value; end; function GetItem(Index: integer): TMyListItemClass; begin Result := TMyListItemClass(FList[Index] ); end; Constructor Create; virtual; begin FList := TList.Create; end; Destructor Destroy; override; begin {don't forget some code to empty list....!!!!} FList.Free; inherited; end; function Add(AItem: TMyListItemClass): integer; begin result := FList.Add(AItem); end; procedure Delete( AIndex: integer ); begin FList.Delete(AIndex); end; function Count: integer; begin Result := FList.Count; end; ----- Original Message ----- From: "James Mills" To: Sent: Sunday, July 06, 2003 4:56 PM Subject: Re: [fpc-pascal]TCollection question > Actually Michael, > > Could you possibly spare 5 mins and give a really simple example of a > TList descandent ? I'm a tad confused here, (too slowly getting > anywhere)... > > Thank you :) > > cheers > James > > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

James Mills
to Matt and Lisa Emson: Why not use a TObjectList?? IIRC that is available. In unit Contnrs.pas. It will do a lot…
Matt and Lisa Emson wrote 12 lines
Why not use a TObjectList?? IIRC that is available. In unit Contnrs.pas. It will do a lot more for you. It can 'own' the objects, and therefore free you from needing to manage them. Simple descendent (typed at speed, with no testing): N.B. This is a WRAPPER because it allows the programmer more control over the interface to the class. However a descendent would work the same way pretty much. You'd probably just alter the 'Add' to 'AddXXX' so as to not clash with 'Add' from TList. Otherwise you would hide the method and make in unavailable. This wrapper is really usefull... I use this basic design all the time!!

A question about your basic-design and using TList (and descandents in general)...

Could I not do this:

TMyList = class(TList);
.
.
.

And thereby extend the basic TList class into a custom List ? The way you use TList is as a private variable in a generic class.

cheers
James

Show quoted text 86 lines
TMyListItemClass = class; {your class to store} TMyList = class private FList: TList; protected procedure SetItem( Index: integer; Value: TMyListItemClass); function GetItem(Index: integer): TMyListItemClass; public Constructor Create; virtual; Destructor Destroy; override; function Add(AItem: TMyListItemClass): integer; procedure Delete( AIndex: integer ); function Count: integer; property Items[Index: integer]: TMyListItemClass read GetItem write SetItem; end; procedure SetItem( Index: integer; Value: TMyListItemClass); begin FList[Index] := Value; end; function GetItem(Index: integer): TMyListItemClass; begin Result := TMyListItemClass(FList[Index] ); end; Constructor Create; virtual; begin FList := TList.Create; end; Destructor Destroy; override; begin {don't forget some code to empty list....!!!!} FList.Free; inherited; end; function Add(AItem: TMyListItemClass): integer; begin result := FList.Add(AItem); end; procedure Delete( AIndex: integer ); begin FList.Delete(AIndex); end; function Count: integer; begin Result := FList.Count; end; ----- Original Message ----- From: "James Mills" To: Sent: Sunday, July 06, 2003 4:56 PM Subject: Re: [fpc-pascal]TCollection question > Actually Michael, > > Could you possibly spare 5 mins and give a really simple example of a > TList descandent ? I'm a tad confused here, (too slowly getting > anywhere)... > > Thank you :) > > cheers > James > > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

Matt Emson
to James Mills

James,

Think of my code as a design pattern for a list, or possibly a template. You could replace the class name you are storing everywhere in the code and would then have a completely different List class. A bit like a C++ template, except you have to define all the code each time.

Show quoted text 6 lines
A question about your basic-design and using TList (and descandents in general)... Could I not do this: TMyList = class(TList);

Yes, but a wrapper gives more flexibility. You can give the class user the exact interface you had in mind, rather than forcing the whole of the TList legacy onto them. The OO term of the month is Aggregation here.

And thereby extend the basic TList class into a custom List ? The way you use TList is as a private variable in a generic class.

Sure you could, but using a wrapper allows you to take more control.

To be honest, you should use a TObjectList anyway. The TObjectList already does almost everything you desire except the specific named class Add/Insert/Items functionality.

Matt

Reply by email