On 28.09.2013 16:37, Xiangrong Fang wrote:
2013/9/28 Sven Barth <pascaldra...@googlemail.com
<mailto:pascaldra...@googlemail.com>>
On second sight your solution is not correct, because you are using
Clone inside your parent class which would not use the (non-virtual)
Clone you created.
What If I make Clone virtual? If by adding "virtual" to Clone, the
problem is solved, then what's the difference between virtual Clone and
the method you provided?
If you want to override the virtual Clone method of TTree<LongInt> in
TIntTree you need to use the same result type + override or otherwise
you gain nothing, because the compiler will not consider the method as
overloaded and use the Clone method of TTree<LongInt> inside
TTree<LongInt>'s methods instead.
=== code begin ===
type
generic TTree<T> = class
private type
TSelfType = TTree;
TSelfClass = class of TSelfType; // earlier I suggested TTree
which 2.6.2 does not support
This compiles, however, if I remove my version of TIntTree (i.e.
implement a Clone in it and call parent's DoClone), then the main
program does not compile, it says:
demo2.lpr(20,13) Error: Incompatible types: got "TIntTree.TTree$LongInt"
expected "TIntTree"
I then can either:
1) add a Clone method to TIntTree and do a typecast inside it, as you said.
2) do a typecast in the main program, i.e. it2 := it1.Clone as TIntTree.
Would you please show how exactly you changed the code? With all those
methods calling each other it's a bit hard to imagine in my head what
you changed. ;)
So, I guess the problem is solved? I have two further questions:
1) Why class of TTree does not work in 2.6.2 but class of TSelfType
worked? Is it a problem of generics in 2.6.2, or it is *not* related to
generics? I feel that TSelfType is same as TTree?
It's a problem of generics in 2.6.2. Principially TSelfType is the same
as TTree, but the 2.6.2 compiler treats them a little bit differently.
2) What is the difference between the following:
- it2 := TIntTree(it1.Clone);
- it2 := it1.Clone as TIntTree;
The latter does a conversion at runtime, so if "it1.Clone" returns an
instance that is not compatible with TIntTree (for example a TObject or
a TTree<LongInt>) then an exception will be raised. The former does not
raise such an exception (but will show you a warning if you try to e.g.
convert a TTree<LongInt> to a TTree<String>, but AFAIK the "as" will
show that warning as well) and does not require additional runtime code
(thus if you know that a e.g. TTree<LongInt> variable really contains a
TIntTree instance you can use the hard typecast). If you compile code
with -CR or {$OBJECTCHECKS ON} then the hard typecast will be the same
as "as".
Where in the official document can I find the behavior/definition of "as"?
Here: http://freepascal.org/docs-html/ref/refsu45.html#x135-14500012.8.7
(Chapter Expressions => Class operators)
Regards,
Sven
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal