Sign in Join

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

Mailing lists / fpc-pascal / 2013-11

virtual method and generics

3 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

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

Xiangrong Fang

Hi,

In my TTree class:
https://github.com/xrfang/fpcollection/blob/master/src/units/tree.pas

I have the following method:

function TTree.Load(s: TStream): Integer;
var
  lv, c: QWord;
  node: TTree;
  buf: Pointer;
begin
  Clear;
  if not ReadNodeData(s, lv, buf, c) then Exit(0);
  DoRestore(buf);
  OnRestore;            //<-- CALL#1
  FreeMem(buf, c);
  Result := 1;
  node := Self;
  while ReadNodeData(s, lv, buf, c) do begin
    while (node  nil) and (lv < node.Level) do node := node.Parent;
    if (lv = node.Level) and (node  Self) then
      node := TTree.Create(Data, node.Parent)
    else
      node := TTree.Create(Data, node);
    node.DoRestore(buf);
    node.OnRestore;      //<-- CALL#2
    FreeMem(buf, c);
    Inc(Result);
  end;
end;

Now I have a problem. CALL#1 is virtual as expected (sub-class's OnRestore is called), but CALL#2 is not virtual, it just call the (empty) OnRestore method defined in TTree.

How to solve this problem?

Thanks!
Xiangrong

Reply by email

Xiangrong Fang
to Xiangrong Fang

2013/11/19 Xiangrong Fang

Show quoted text 7 lines
Now I have a problem. CALL#1 is virtual as expected (sub-class's OnRestore is called), but CALL#2 is not virtual, it just call the (empty) OnRestore method defined in TTree. How to solve this problem?

BTW, this also does NOT solve the problem:

TSelfType(node).OnRestore; ​​

Reply by email

Sven Barth
to Xiangrong Fang: In my TTree class: https://github.com/xrfang/fpcollection/blob/master/src/units/tree.pas…
"Xiangrong Fang" wrote
Hi, In my TTree class:

https://github.com/xrfang/fpcollection/blob/master/src/units/tree.pas

Show quoted text 30 lines
I have the following method: function TTree.Load(s: TStream): Integer; var lv, c: QWord; node: TTree; buf: Pointer; begin Clear; if not ReadNodeData(s, lv, buf, c) then Exit(0); DoRestore(buf); OnRestore; //<-- CALL#1 FreeMem(buf, c); Result := 1; node := Self; while ReadNodeData(s, lv, buf, c) do begin while (node nil) and (lv < node.Level) do node := node.Parent; if (lv = node.Level) and (node Self) then node := TTree.Create(Data, node.Parent) else node := TTree.Create(Data, node); node.DoRestore(buf); node.OnRestore; //<-- CALL#2 FreeMem(buf, c); Inc(Result); end; end; Now I have a problem. CALL#1 is virtual as expected (sub-class's

OnRestore is called), but CALL#2 is not virtual, it just call the (empty) OnRestore method defined in TTree.

How to solve this problem?
The problem is that you are creating a TTree instance (the TTree.Create)
and not an instance of the current node type. Use "node :=
TTree(ClassType).Create(...)" instead of "node := TTree.Create(...)" at the
two locations where you create the node.

Also this problem is not related to generics, but would happen in a non-generic class as well.

Regards,
Sven

Reply by email