Antwort und Beispiellösung
Content |
Antwort zur Frage
Die Zuweisung „old->next = nullptr;“ ist notwendig, weil sonst rekursiv die gesamte Liste freigegeben wird. Wir wollen aber nur das ganz oben liegende Objekt des Typs IntegerMember freigeben.
Beispiellösung
#include <cassert> #include <iostream> class IntegerMember { public: IntegerMember(int member, IntegerMember* next) : member(member), next(next) { } IntegerMember(const IntegerMember& other) : member(other.member), next( other.next? new IntegerMember(*other.next) : nullptr ) { } ~IntegerMember() { delete next; } IntegerMember& operator=(const IntegerMember& other) { delete next; member = other.member; if (other.next) { next = new IntegerMember(*other.next); } else { next = nullptr; } return *this; } int member; IntegerMember* next; }; class IntegerStack { public: IntegerStack() : top(nullptr) { } IntegerStack(const IntegerStack& other) : top( other.top? new IntegerMember(*other.top) : nullptr ) { } ~IntegerStack() { delete top; } IntegerStack& operator=(const IntegerStack& other) { delete top; if (other.top) { top = new IntegerMember(*other.top); } else { top = nullptr; } return *this; } 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); { IntegerStack b{a}; print("b", b); } { IntegerStack c; c = a; print("c", c); } print("a", a); }
heim$ diff -U 2 simple-stack2.cpp simple-stack-fixed.cpp --- simple-stack2.cpp 2018-05-03 14:51:49.000000000 +0200 +++ simple-stack-fixed.cpp 2018-05-07 10:03:50.000000000 +0200 @@ -7,7 +7,26 @@ member(member), next(next) { } + IntegerMember(const IntegerMember& other) : + member(other.member), + next( + other.next? + new IntegerMember(*other.next) + : + nullptr + ) { + } ~IntegerMember() { delete next; } + IntegerMember& operator=(const IntegerMember& other) { + delete next; + member = other.member; + if (other.next) { + next = new IntegerMember(*other.next); + } else { + next = nullptr; + } + return *this; + } int member; IntegerMember* next; @@ -18,7 +37,24 @@ IntegerStack() : top(nullptr) { } + IntegerStack(const IntegerStack& other) : + top( + other.top? + new IntegerMember(*other.top) + : + nullptr + ) { + } ~IntegerStack() { delete top; } + IntegerStack& operator=(const IntegerStack& other) { + delete top; + if (other.top) { + top = new IntegerMember(*other.top); + } else { + top = nullptr; + } + return *this; + } void push(int member) { top = new IntegerMember(member, top); heim$ g++-8.3 -Wall -g -o simple-stack-fixed simple-stack-fixed.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-stack-fixed valgrind: ./simple-stack-fixed: No such file or directory heim$