seien folgende Klassendeklaration:Destruktor einer Klasse C mit Mitgliedern der Zeiger C
class NTree
{
private:
const T* fKey;
NTree<T, N>* fNodes[N]; // N subtrees of degree N
NTree();
...
}
in denen wir einige Fnodes hinzufügen können, die eine Teilstruktur ein Index angegeben. Diese werden dynamisch unter Verwendung von new
zugewiesen. Allerdings gibt es Elemente, die statisch sind, und nicht dynamisch zugewiesen:
public:
static NTree<T, N> NIL; // sentinel
...
Wir wählen diese oben mit dem mitgelieferten Standard-Konstruktor auf dem Stapel zuzuordnen.
template<class T, int N>
NTree<T, N> NTree<T, N>::NIL;
Nun wollen wir einen NTree löschen. Die Klasse NTree ist rekursiv und enthält einen Zeiger auf NTree. Das ist, was ich kämpfe.
Ich verstehe die Logik hinter einem Destruktor, wenn wir z.B.
Wir könnten einen Destruktor verwenden, um zu verhindern, dass diese Zeiger baumeln oder verloren gehen.
~MyClass()
{
delete myA;
delete myB;
delete myC;
}
Wenn es jedoch zu einer rekursiven Klasse kommt, ich habe keine Ahnung, wie meine Gedanken um diese zu wickeln, wie die Löschung zu verstehen.
Eine einfache Sache zu denken:
template<class T, int N>
NTree<T, N>::~NTree()
{
delete[] fNodes;
}
Allerdings wird es nicht funktionieren, da einige Knoten sind NIL (Stack zugeordnet), so löschen sie in einem Absturz führen.
Eine weitere Idee ist:
template<class T, int N>
NTree<T, N>::~NTree()
{
for (int i = 0; i < N; i++)
{
delete fNodes[i];
}
}
Dies ist jedoch in einem Stapelüberlauf führen, weil der Stapel mit Frames für jeden rekursiven Aufruf von ~NTree()
und die folgenden bombardiert:
template<class T, int N>
NTree<T, N>::~NTree()
{
for (int i = 0; i < N; i++)
{
if (fNodes[i] != &NIL)
delete fNodes[i];
}
}
Ergebnisse in einer Leseausnahme, weil die rekursiven Aufrufe fNodes [i] für einen bestimmten Stapelrahmen freigeben und so versuchen, auf mich zuzugreifen mory ist ungültig.
Also meine Frage ist, wie kann ich eine Elementvariable löschen, wo dieses Mitglied rekursiv als die gleiche Klasse definiert ist?
Wie kann ich meinen Destruktor arbeiten lassen?
Edit: Versuch mehr Informationen zu versorgen, ohne dass es zu verworren machen
ich ein destructor bin definieren, so dass es wahrscheinlich klug, du meine Kopie zu zeigen, Konstruktor und Zuweisungsoperator:
template<class T, int N>
NTree<T, N> & NTree<T, N>::operator=(const NTree & aOtherNTree)
{
//This is an already initialized object.
if (this != &aOtherNTree)
{
fKey = aOtherNTree.fKey;
for (int i = 0; i < N; i++)
{
if (fNodes[i] == &NIL)
continue; //continue if nil
delete fNodes[i]; //important -- so no dangling pointer
fNodes[i] = new NTree<T, N>; //allocate memory
fNodes[i] = aOtherNTree.fNodes[i]; //assign
}
}
return *this;
}
. .
Ich hoffe, dies zeigt alle Instanzen von, wenn ich Speicher zuweisen, die explizite Löschung im Destruktor benötigt. NIL ist ein Wächter, wir weisen NIL immer ein Blatt zu.
Dieser Teil des Professors zur Verfügung gestellt wird, ist es, wo wir die ersten Objekte einrichten:
NS3Tree root(A);
root.attachNTree(0, *(new NS3Tree(A1)));
root.attachNTree(1, *(new NS3Tree(A2)));
root.attachNTree(2, *(new NS3Tree(A3)));
root[0].attachNTree(0, *(new NS3Tree(AA1)));
root[1].attachNTree(0, *(new NS3Tree(AB1)));
root[1].attachNTree(1, *(new NS3Tree(AB2)));
A1, A2, usw. sind sind Strings
'delete [] fNodes' 'fNodes' wurde nicht mit' new' versehen, so dass Sie kein Geschäft haben, es zu löschen. Vielleicht möchten Sie einzelne Elemente des Arrays löschen, vorausgesetzt, dass * diese * mit 'neu' erhalten wurden. –
@IgorTandetnik Ah, ja. Du hast recht. das Löschen von fNodes würde in diesem Fall definitiv nicht funktionieren. Ich zeige jedoch zwei Methoden, in denen ich versuche, auch die Elemente von fNodes zu löschen, aber ohne Erfolg. – Kevin
Durchqueren Sie zuerst die Baumtiefe (unter Verwendung eines expliziten Stapels, nicht rekursiver Aufrufe). Löschen Sie die Knoten von unten nach oben. –