Board index » cppbuilder » TMyCollection::Assign ?

TMyCollection::Assign ?


2007-11-15 07:04:19 AM
cppbuilder44
Hi there
Ive been looking at the source for TCustomListView
And TListColumns, but I cant find an assign function.
Does that mean that it isn't nesesary ?
In my CollectionItems i have a lot of properties
and I have written an assign function for those
but will that be called if I don't write an assign
function for my collection ?
I have written one see below, but if it isn't necessary
I'll just remove it again.
Thanks in advance
Asger
void __fastcall T_Columns::Assign(TPersistent* Source)
{
T_Columns* SrcCols = dynamic_cast<T_Columns*>(Source);
if( ! SrcCols)throw EConvertError("Asigning wrong type to TAjHeader->Columns");
BeginUpdate();
Clear();
int C = SrcCols->Count;
for(int i = 0; i < C; ++i)
{
Add()->Assign(SrcCols->Items[i]);
}
EndUpdate();
}
//---------------------------------------------------------------------------
 
 

Re:TMyCollection::Assign ?

"Asger Joergensen" < XXXX@XXXXX.COM >wrote in message
Quote
Ive been looking at the source for TCustomListView
And TListColumns, but I cant find an assign function.
Most VCL classes do not implement Assign(). Many classes that derive
directly from TPersistent do, though.
Quote
Does that mean that it isn't nesesary ?
It merely means those classes decided not to implement it. In this
particular case, TCollection and TListItem are the ones who implement
Assign(), however.
Quote
In my CollectionItems i have a lot of properties
and I have written an assign function for those
but will that be called if I don't write an assign
function for my collection ?
Yes, because TCollection implements Assign() the same way you did manually
(although your type checking was a bit misguided, and you didn't protect
Begin/EndUpdate() from exceptions being thrown).
Quote
I have written one see below, but if it isn't necessary I'll
just remove it again.
You can remove it from your TCollection-derived class, but leave it in your
TCollectionItem-derived class.
Gambit
 

Re:TMyCollection::Assign ?

Hi Remy
Remy Lebeau (TeamB) says:
Quote

Yes, because TCollection implements Assign() the same way you did manually
(although your type checking was a bit misguided, and you didn't protect
Begin/EndUpdate() from exceptions being thrown).
Misguided in what way, I'am trying to learn.
void __fastcall T_Columns::Assign(TPersistent* Source)
{
T_Columns* SrcCols = dynamic_cast<T_Columns*>(Source);
if( ! SrcCols)
throw EConvertError("Asigning wrong type to TAjHeader->Columns");
BeginUpdate();
try{
Clear();
int C = SrcCols->Count;
for(int i = 0; i < C; ++i)
{
Add()->Assign(SrcCols->Items[i]);
}
}__finally{
EndUpdate();
}
}
I will remove it, I would just like to get it right
before I do so.
I find this TCollection stuff a bit difficult since
most of the functions are not virtual, but I kind of
override them anyway, I know it's a different signature
and I am getting there, but goes a little slow..;-)
Thanks for Your help
Kind regards
Asger
 

{smallsort}

Re:TMyCollection::Assign ?

"Asger Joergensen" < XXXX@XXXXX.COM >wrote in message
Quote
Misguided in what way, I'am trying to learn.
You are throwing your own exception instead of calling the base class
Assign(). By calling the inherited Assign(), you give the Source object a
chance to copy itself to the collection via TPersistent::AssignTo() instead.
Just because T_Columns does not know how to copy from a non-T_Columns object
does not automatically mean that the non-T_Columns object does not know how
to copy to a T_Columns object (that's rarely the case, but it is good to
support, just in case).
For example:
void __fastcall T_Columns::Assign(TPersistent* Source)
{
// this step is optional...
if( Source == NULL )
{
Clear();
return;
}
T_Columns* SrcCols = dynamic_cast<T_Columns*>(Source);
if( SrcCols )
{
if( SrcCols != this )
{
BeginUpdate();
try
{
Clear();
int C = SrcCols->Count;
for(int i = 0; i < C; ++i)
Add()->Assign(SrcCols->Items[i]);
}
__finally
{
EndUpdate();
}
}
}
else
inherited::Assign(Source);
}
Quote
I find this TCollection stuff a bit difficult since
most of the functions are not virtual
They don't need to be.
Gambit
 

Re:TMyCollection::Assign ?

Hi Remy
Thanks for explaining, I think I get it now.;-)
There is one thing though, in the TCollection.Assign
code they call Add in this way:
Add.Assign(TCollection(Source).Items[I]);
And sice Add is not wirtual I think it is the
TCollection.Add there is called and not
TMyCollection.Add
In my Add function I position the Button on the
header control, so I need it to be my add there
is called.
So my last question is which add is called in
the TCollection.Assign ??
Thanks for all Your help!
Kind regards
Asger
 

Re:TMyCollection::Assign ?

"Asger Joergensen" < XXXX@XXXXX.COM >wrote in message
Quote
sice Add is not wirtual I think it is the
TCollection.Add there is called and not
TMyCollection.Add
Correct. But that is perfectly fine, since TCollection::Add() will create
an instance of your TCollectionItem-derived class type, so the correct
overriden Assign() will be called via polymorphism.
Quote
In my Add function I position the Button on the
header control, so I need it to be my add there
is called.
Add() is not the correct place to do that in the first place. Do it in your
TCollectionItem's constructor instead, and then move it around in Assign()
as needed.
Quote
which add is called in the TCollection.Assign ??
TCollection::Add().
Gambit
 

Re:TMyCollection::Assign ?

Hi Remy
Thank You very much for helping me understand this.
Kind regards
Asger