Klassen mit dynamische Datenstrukturen
Content |
Etwas komplizierter wird es, wenn Objekte bzw. deren Klassen dynamische Datenstrukturen unterhalten. Es lohnt sich, dies zuerst an einer trivialen Stack-Implementierung anzusehen. Gegeben sei folgende Klasse IntegerStack mit der Hilfsklasse IntegerMember, bei der momentan noch die Kopierkonstruktoren und Zuweisungsoperatoren fehlen:
#include <cassert> #include <iostream> class IntegerMember { public: IntegerMember(int member, IntegerMember* next) : member(member), next(next) { } ~IntegerMember() { delete next; } int member; IntegerMember* next; }; class IntegerStack { public: IntegerStack() : top(nullptr) { } ~IntegerStack() { delete top; } void push(int member) { top = new IntegerMember(member, top); } bool empty() { return top == nullptr; } int pop() { assert(top != nullptr); int member = top->member; IntegerMember* old = top; top = top->next; old->next = nullptr; delete old; return member; } private: IntegerMember* top; }; void print(const char* name, IntegerStack& s) { std::cout << name << ":"; while (!s.empty()) { std::cout << " " << s.pop(); } std::cout << std::endl; } int main() { IntegerStack a; a.push(1); a.push(2); a.push(3); print("a", a); }
Wenn Sie diese Fassung ausprobieren, scheint es zunächst zu klappen:
heim$ g++-8.3 -Wall -g -o simple-stack simple-stack.cpp /usr/local/libexec/gcc/x86_64-pc-linux-gnu/8.3.0/cc1plus: error while loading shared libraries: libmpfr.so.4: cannot open shared object file: No such file or directory heim$ ./simple-stack sh: 1: ./simple-stack: not found heim$ valgrind ./simple-stack valgrind: ./simple-stack: No such file or directory heim$
Anders sieht es aber aus, wenn die vom Übersetzer gelieferten Kopierkonstruktor und Zuweisungsoperatoren zum Einsatz kommen:
heim$ diff -U 2 simple-stack.cpp simple-stack2.cpp --- simple-stack.cpp 2018-05-03 14:34:32.000000000 +0200 +++ simple-stack2.cpp 2018-05-03 14:51:49.000000000 +0200 @@ -50,4 +50,12 @@ int main() { IntegerStack a; a.push(1); a.push(2); a.push(3); + { + IntegerStack b{a}; + print("b", b); + } + { + IntegerStack c; c = a; + print("c", c); + } print("a", a); } heim$ g++-8.3 -Wall -g -o simple-stack2 simple-stack2.cpp /usr/local/libexec/gcc/x86_64-pc-linux-gnu/8.3.0/cc1plus: error while loading shared libraries: libmpfr.so.4: cannot open shared object file: No such file or directory heim$ valgrind ./simple-stack2 valgrind: ./simple-stack2: No such file or directory heim$
Frage
Wozu ist die Anweisung old->next = nullptr; notwendig in der Methode pop der Klasse IntegerStack?
Aufgabe
Ergänzen Sie die obige Fassung mit Kopierkonstruktoren und Zuweisungsoperatoren, so dass alles ordnungsgemäß läuft und valgrind keine Fehler liefert. Machen Sie sich dabei das Leben so einfach wie möglich. Schleifen werden keine benötigt, da sich alles rekursiv erledigen lässt.