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.