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 .
精彩评论