开发者

Delphi Delete TNode, incompatible type TNodePtr

I have a binary tree class that is created with a root node and nodes can be added to it as needed in the code, however I am having trouble in deleting the nodes because I point to them with TNodePtr and it is an incompatible type with TNode. At 开发者_JAVA百科the moment I have this recursive method of deleting nodes which should work once the incompatible types is sorted. Thanks.

Destructor TTree.Destroy;
procedure FreeSubnodes(Node: TNodePtr);
begin
        if Assigned(Node.Left) then
                FreeSubnodes(Node.Left);
        if Assigned(Node.Right) then
                FreeSubnodes(Node.Right);
        Delete(Node);
end;
begin
        FreeSubnodes(Root);
        inherited;
end;

Edit 04/03/2010: The error given is this: [Warning] SystemBuild.pas(50): Method 'Destroy' hides virtual method of base type 'TObject' [Error] SystemBuild.pas(84): Incompatible types

Line 84 is Delete(Node);

I declared the node like this:

type
    TNodePtr = ^TNode;
    TNode = Record
        Data:String;
        Left:TNodePtr;
        Right:TNodePtr;
    end;

And the tree like this:

Type
    TTree = Class
    Private
        Root:TNodePtr;
    Public
        Function GetRoot:TNodePtr;
        Constructor Create;
        Destructor Destroy;
    end;


The error you see is because of a mistake I made in the answer I gave to your previous question. I wrote Delete when I should have written Dispose. I apologize. Here, then, is the correct destructor implementation:

destructor TTree.Destroy;
  procedure FreeSubnodes(Node: PNode);
  begin
    if Assigned(Node.Left) then
      FreeSubnodes(Node.Left);
    if Assigned(Node.Right) then
      FreeSubnodes(Node.Right);
    Dispose(Node);
  end;
begin
  FreeSubnodes(Root);
  inherited;
end;

The error is not saying that TNodePtr is incompatible with TNode. The error just says "incompatible types" because the compiler doesn't know what type Delete is supposed to receive. It's a compiler-magic function that accepts several different parameter types, none of which is compatible with TNodePtr.

The first compiler message you see is about your Destroy method hiding the method from the base class. It's not responsible for the problem you were seeing, but you'd eventually notice a problem because your destructor would never get called. When you call Free, it will call TObject's Destroy method, not your new version. To make yours get called instead, you need to mark yours as overriding the inherited version. Then, when TObject.Free calls Destroy, control will go to your version first, and then go to the base class's version when you call inherited. Change the declaration to this:

destructor Destroy; override;


Destructor TTree.Destroy;
    procedure FreeSubnodes(Node: TNodePtr);
    var
        ThisNode:TNode;
    begin
        ThisNode := Node^;
            if Assigned(ThisNode.Left) then
                    FreeSubnodes(ThisNode.Left);
            if Assigned(ThisNode.Right) then
                    FreeSubnodes(ThisNode.Right);
            Dispose(Node);
    end;
begin
        FreeSubnodes(Root);
        inherited;
end;


to dereference the pointer use Node^


use TComponent instead of Record. Record type(Pointer) is old and unsafe . TComponent is easier and more abstract. your issue similar to https://stackoverflow.com/a/1032252/528588 .

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜