On 29.09.2013 11:47, Xiangrong Fang wrote:
2013/9/29 Sven Barth <pascaldra...@googlemail.com
<mailto:pascaldra...@googlemail.com>>


    I would suggest you to add an additional protected virtual method to
    TTree<> which is called from TTree<>.Clone and you override that in
    your descendant classes.


Could
​ you please give an example how to do this?  I tried the following:

=== code start ===
function TTree.DoClone: TTree; //protected, virtual
begin
   Result := TSelfClass(Self.ClassType).Create(Data, FParent);
end;

function TTree.Clone: TTree;
var
   node: TTree;
begin
   Result := DoClone;
   node := FirstChild;
   while node <> nil do begin
     node.Clone.Remove(Result);
     node := node.NextSibling;
   end;
end;
=== code end ===

However, this does not work, because it seems that I cannot make any
generic method virtual!  In TIntTree, I have to write:

function TIntTree.DoClone: TIntTree;

As it is not possible to write TTree outside of the generic definition.

This should do it:

=== code begin ===

type
  generic TTree<T> = class
  protected type
    TSelfType = TTree;
  protected
    procedure DoClone(aNode: TSelfType); virtual;
  public
    function Clone: TSelfType;
  end;

procedure TTree.DoClone(aNode: TSelfType);
begin
  (* empty *)
end;

function TTree.Clone: TSelfType;
var
  n: TTree;
begin
  Result := TSelfType(Self.ClassType).Create(Data, FParent);

  node := FirstChild;
  while node <> nil do begin
    node.Clone.Remove(Result);
    node := node.NextSibling;
  end;

  DoClone(Result);
end;


type
  TIntTree = class(specialize TTree<Integer>)
  protected
    procedure DoClone(aNode: TSelfType; override;
  end;

procedure TIntTree.DoClone(aNode: TSelfType);
begin
  inherited;
  (* whatever *)
end;

=== code end ===

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to