2010-03-03 7 views
2

루트 노드로 만든 이진 트리 클래스가 있는데 코드에 필요에 따라 노드를 추가 할 수 있지만 노드를 가리킬 때 문제가 있습니다. TNodePtr과 호환되지 않으며 TNode와 호환되지 않는 유형입니다. 현재이 호환되지 않는 유형이 정렬되면 작동해야하는 노드를 삭제하는 재귀 적 방법이 있습니다. 감사.Delphi Delete TNode, 호환되지 않는 유형 TNodePtr

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; 

편집 2010년 4월 3일 (50) [경고] SystemBuild.pas : 방법 "파괴"기본 유형의 가상 메소드를 숨기는 'TObject의' [오류]에서는 SystemBuild 주어진 오류가 이쪽 .pas (84) : 호환되지 않는 유형

라인 84는 삭제 (노드)입니다. 이 같은

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

그리고 나무 :

는이 같은 노드 선언 된 포인터를 사용 노드 역 참조에

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

TNode 및 TNodePtr 선언을 표시해야합니다. –

+2

* 전체 오류 메시지 *를 인용하고 어떤 라인이 발생하는지 알려주십시오. –

+0

이제 오류 및 선언을 편집에 추가했습니다. 미안 나는 처음에 약간의 서두를했다. – BookOfGreg

답변

3

표시되는 오류입니다 실수로 인해 나는 your previous question에게 준 대답을 만들었습니다. I wrote Delete 내가 Dispose로 작성해야합니다. 사과드립니다.

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; 

이 오류는 TNodePtrTNode와 호환되지 않는 것을 말하는되지 않은 : 여기에, 다음, 올바른 소멸자 구현입니다. 컴파일러는 Delete 형식을 알 수 없으므로이 오류는 "호환되지 않는 형식"이라고 표시됩니다. 이것은 여러 가지 매개 변수 유형을 받아들이는 컴파일러 - 매직 함수로, 어느 것도과 호환되지 않습니다.

첫 번째 컴파일러 메시지는 Destroy 메서드가 기본 클래스에서 메서드를 숨기는 것에 대한 것입니다. 그것은 당신이 보았던 문제에 책임이 없지만 소멸자가 결코 불려 가지 않을 것이기 때문에 결국 문제를 발견하게 될 것입니다. Free으로 전화하면 새 버전이 아닌 TObject 'sDestroy 메서드를 호출합니다. 대신 전화를 받으려면 을 상속받은 버전 인으로 대체해야합니다. 그런 다음 TObject.FreeDestroy이라고하면 컨트롤이 먼저 사용자의 버전으로 이동 한 다음 inherited에 전화 할 때 기본 클래스의 버전으로 이동합니다. 선언을 다음으로 변경하십시오.

destructor Destroy; override; 
+0

나는 뒤돌아 본 당신이 원래 코드에서 실수를 한 것 같지 않습니다. 처음에는 "폐기"라고 말합니다. 그 이후로 모든 루프를 재귀 적으로 변경했지만 간단하게 만들었고 재귀 적 소멸자를 사용했지만 분명히 잘못한 것처럼 보입니다. 이 비트가 필요합니까? "할당 된 경우 (root.left) FreeSubnodes (Root.Left) 할당 된 경우 (Root.Right) FreeSubnodes (Root.Right); 상속 된 경우" 어쨌든 소멸자의 내부는 root.left와 root.right에 도착할 것이기 때문에 ... – BookOfGreg

+0

재귀 적 소멸자가 없습니다. TTree 객체는 하나뿐입니다. 노드는 객체가 아닙니다. 그들은 소멸자가 없습니다. Root의 선언을 TNode로 변경했다면 Root.Left와 Root.Right를 별도로 해제해야합니다. 왜냐하면 FreeSubnode는 Root 자체에서 호출 될 수 없기 때문입니다. –

+0

* 이전에 삭제 했어. 이 답변의 첫 번째 버전을 작성하면서이 문제를 발견했습니다. 나는 이전 답안에서 실수를 고쳐서 장래에 만난 다른 모든 사람들이 나쁜 코드에 얽매이지 않게 할 것이다. 나는 또한 당신이 변경했을 수도있는 모든 것들을 추측하는 것이 아니라 내 실수로 인한 것이라는 사실에 더 중점을 두어이 대답을 바꾸었다. –

0

을^

+2

델파이 버전에 따라 컴파일러에 의해 "자동으로"수행됩니다. –

+0

델파이의 버전은 델파이 7입니다. – BookOfGreg

1
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; 
관련 문제