| View previous topic :: View next topic |
| Author |
Message |
Alan Mead Guest
|
Posted: Tue Jan 18, 2005 8:10 am Post subject: newbie question sabout class design |
|
|
I am writing a simulation where a population object has to hold
a series of people objects.
I'm using a TList to hold the people but I have to cast each time, like this:
Result := Result + Person(Peops.Items[i]).Fitness;
So, is TList the best way for one class to hold a series of objects?
And if so, one book recommends creating a wrapper around TList to avoid
the casts. I'm probably doing it wrong because I still have to cast.
Here's my wrapper:
TPeopList = class(Tlist)
public
procedure Add(p: Person);
constructor Create;
destructor Destroy; override;
end;
Which doesn't help at all. I guess because I need to add an Items
property. But I'm stuck here:
property Items[i: Integer]: Person read ??? write ???; default;
I don't know what to put for the ??? marks...
And in general, can I get away with all of the methods being just an
inherited statement? Or do I need to make a cast:
procedure TPeopList.Add(p: Person);
begin
inherited; // can it be this simple?
inherited Add(pointer(p)); // or do I need to do this?
??? // or am I completely lost?
end;
Thanks!
-Alan
|
|
| Back to top |
|
 |
Tom de Neef Guest
|
Posted: Tue Jan 18, 2005 9:13 am Post subject: Re: newbie question sabout class design |
|
|
"Alan Mead" <amead (AT) comcast (DOT) net> schreef in bericht
news:pan.2005.01.18.08.10.04.227007 (AT) comcast (DOT) net...
| Quote: | I am writing a simulation where a population object has to hold
a series of people objects.
I'm using a TList to hold the people but I have to cast each time, like
this:
Result := Result + Person(Peops.Items[i]).Fitness;
So, is TList the best way for one class to hold a series of objects?
|
Try along following lines:
type
TpeopleList = class(Tlist)
private
function getItem(index : integer) : Tpeople;
procedure putItem(index : integer; person : Tpeople);
public
property items[index : integer]: Tpeople read getItem write putItem;
default;
procedure add(person : Tpeople);
end;
function TpeopleList.getItem(index : integer) : Tpeople;
begin result:=Tpeople(inherited items[index]) end;
procedure TpeopleList.putItem(index : integer; person : Tpeople);
begin inherited items[index]:=pointer(person) end;
procedure TpeopleList.add(person : Tpeople);
begin inherited add(pointer(person)) end;
You can now call without casting:
peopleList.add(person);
person:=peopleList[i];
peopleList[k]:=person;
etc.
Tom
|
|
| Back to top |
|
 |
AlanGLLoyd Guest
|
Posted: Wed Jan 19, 2005 9:48 pm Post subject: Re: newbie question sabout class design |
|
|
In article <pan.2005.01.18.08.10.04.227007 (AT) comcast (DOT) net>, Alan Mead
<amead (AT) comcast (DOT) net> writes:
| Quote: | I am writing a simulation where a population object has to hold
a series of people objects.
I'm using a TList to hold the people but I have to cast each time, like this:
|
As you will most likely want to do things with individual people and with the
population, I would use descendants of TCollecton/TCollectionItem. These have
the skeleton and glue to hold together a collection of similar objects, and
incorporates a TList class (has been recommended), but you would still have to
do a typecast on access of the descendants of TCollectionItem - somewhat like
(from TPools / TPool classes where TPools descends from TCollection and TPool
descends from TCollectionItem)...
function TPools.Add: TPool;
{this function saves having to typecast every access
of the collection item returned from inherited Add}
begin
Result := TPool(inherited Add);
end;
function TPools.GetItems(Index : integer) : TPool;
{this function saves having to typecast every access of the
collection item returned from inherited access to inherited Items}
begin
Result := TPool(inherited Items[Index]);
end;
I can dig up an example of TCollection/TCollectionItem if you would like it -
email me.
| Quote: | Which doesn't help at all. I guess because I need to add an Items
property. But I'm stuck here:
property Items[i: Integer]: Person read ??? write ???; default;
I don't know what to put for the ??? marks...
|
Look up "array properties" in Delphi help
| Quote: | And in general, can I get away with all of the methods being just an
inherited statement?
|
You don't have to code that unles you are overiding (adding additional code to
the functionality of the parent) a method of the parent. Object orientation
automatically calls the method of a descendant if that method in not overridden
(or hidden by redeclaring without the "override" directive). Look up "virtual"
in Delphi help.
Alan Lloyd
[email]alanglloyd (AT) aol (DOT) com[/email]
|
|
| Back to top |
|
 |
Martin Harvey (work) Guest
|
Posted: Fri Jan 21, 2005 2:37 pm Post subject: Re: newbie question sabout class design |
|
|
| Quote: | Here's my wrapper:
TPeopList = class(Tlist)
public
procedure Add(p: Person);
constructor Create;
destructor Destroy; override;
end;
Which doesn't help at all. I guess because I need to add an Items
property. But I'm stuck here:
property Items[i: Integer]: Person read ??? write ???; default;
I don't know what to put for the ??? marks...
You need to provide GetXXX- and SetXXX methods, like:
|
Although I would not use inheritance in this case, because you can't *hide*
existing TList behaviour. It's often better to enclapsulate the TList in
another class:
type
TContained = class(whatever...)
TMyContainer = class
private
FList: TList;
public
... blah blah
MH.
|
|
| Back to top |
|
 |
Martin Harvey (work) Guest
|
Posted: Fri Jan 21, 2005 3:38 pm Post subject: Re: newbie question sabout class design |
|
|
| Quote: | do a typecast on access of the descendants of TCollectionItem - somewhat
like
(from TPools / TPool classes where TPools descends from TCollection and
TPool
descends from TCollectionItem)...
|
Another option is to make the container contain a class reference type which
indicates what the type of the contained objects should be. You still have
to cast, but at least you can type check.
MH.
|
|
| Back to top |
|
 |
David Reeve Guest
|
Posted: Sat Jan 22, 2005 12:43 am Post subject: Re: newbie question sabout class design |
|
|
"Martin Harvey (work)" <m.harvey (AT) nospam (DOT) snellwilcox.com> wrote
| Quote: |
do a typecast on access of the descendants of TCollectionItem - somewhat
like
(from TPools / TPool classes where TPools descends from TCollection and
TPool
descends from TCollectionItem)...
Another option is to make the container contain a class reference type
which
indicates what the type of the contained objects should be. You still have
to cast, but at least you can type check.
|
Isn't this standard behaviour for TCollection? You nominate the class of
the item when your create the collection........
TCollection.Create(ItemClass: TCollectionItemClass)
Dave
|
|
| Back to top |
|
 |
Martin Harvey (Demon acco Guest
|
Posted: Sat Jan 22, 2005 1:49 am Post subject: Re: newbie question sabout class design |
|
|
On Sat, 22 Jan 2005 00:43:58 GMT, "David Reeve"
<dree4456 (AT) big-pond (DOT) net.au> wrote:
| Quote: | Isn't this standard behaviour for TCollection? You nominate the class of
the item when your create the collection........
TCollection.Create(ItemClass: TCollectionItemClass)
|
Dunno, I've never used TCollection(!) - it's just that the classes I
like stuffing into lists rarely descend from TCollectionItem :-)
MH.
|
|
| Back to top |
|
 |
AlanGLLoyd Guest
|
Posted: Sun Jan 23, 2005 6:14 am Post subject: Re: newbie question sabout class design |
|
|
In article <ilhId.128457$K7.98376 (AT) news-server (DOT) bigpond.net.au>, "David Reeve"
<dree4456 (AT) big-pond (DOT) net.au> writes:
| Quote: | Isn't this standard behaviour for TCollection? You nominate the class of
the item when your create the collection........
TCollection.Create(ItemClass: TCollectionItemClass)
|
Yes
Alan Lloyd
[email]alanglloyd (AT) aol (DOT) com[/email]
|
|
| Back to top |
|
 |
|