1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
#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);
}