title: C++11 Correct usage of smart pointers in a doubly linked list
body: <p>I am trying to use some new design techniques to implement a linked list,</p>
  
  <p>but I can't seem to figure out just the right way to do it .</p>
  
  <p>The techniques are smart pointers and the null object pattern .</p>
  
  <p>The problems I'm having are with the destruction of the entire list ,</p>
  
  <p>I had one implementation where it did not destruct a few objects,</p>
  
  <p>now I seem to have a cyclic problem and it does not exit at all.</p>
  
  <p>Follows the code:</p>
  
  <p>linkedlist.h</p>
  
  <pre><code>    #pragma once
      #include &lt;memory&gt;
      #include "node.h"
  
      class LinkedList {
      public:
          LinkedList() : m_size(0), head(nullptr) {};
          void addNode(int value);
          void removeNode(int index);
      private:
          std::shared_ptr&lt;Node&gt; getNodeAtIndex(int index);
          std::shared_ptr&lt;Node&gt; getLastNode();
          void _addNode(int value);
          inline void increaseSize() { ++m_size; }
          inline void decreaseSize() { --m_size; }
      private:
          size_t m_size;
          std::shared_ptr&lt;Node&gt; head;
      };
  </code></pre>
  
  <p>linkedlist.cpp</p>
  
  <pre><code>    #include "linkedlist.h"
  
      void LinkedList::addNode(int value) {
          _addNode(value);
          increaseSize();
      }
  
      void LinkedList::_addNode(int value) {
          if (nullptr == head) {
              head = std::make_shared&lt;Node&gt;(Node(value));
              return;
          }
          std::shared_ptr&lt;Node&gt; tail = getLastNode();
          std::shared_ptr&lt;Node&gt; nextNode = std::make_shared&lt;Node&gt;(Node(value));
          nextNode-&gt;setPrevious(tail);
          tail-&gt;setNext(nextNode);
      }
  
      void LinkedList::removeNode(int index) {
          std::shared_ptr&lt;Node&gt; node = getNodeAtIndex(index);
          node-&gt;getNext()-&gt;setPrevious(node-&gt;getPrevious());
          node-&gt;getPrevious()-&gt;setNext(node-&gt;getNext());
          decreaseSize();
      }
  
      std::shared_ptr&lt;Node&gt; LinkedList::getNodeAtIndex(int index) {
          std::shared_ptr&lt;Node&gt; node = head;
          for (int i = 0; i &lt; index; ++i) {
              node = node-&gt;getNext();
          }
          return node;
      }
  
      std::shared_ptr&lt;Node&gt; LinkedList::getLastNode() {
          return getNodeAtIndex(m_size-1);
      }
  </code></pre>
  
  <p>Node.h</p>
  
  <pre><code>    #pragma once
      #include &lt;memory&gt;
  
      class Node {
      public:
          Node() : value(0), next(nullptr), previous(nullptr) {};
          Node(int value) : value(value) {};
          ~Node() { printf("%d", value); };
          std::shared_ptr&lt;Node&gt; getNext();
          virtual void setNext(std::shared_ptr&lt;Node&gt; newNext);
          std::shared_ptr&lt;Node&gt; getPrevious();
          virtual void setPrevious(std::shared_ptr&lt;Node&gt; newPrevious);
      private:
          int value;
          std::shared_ptr&lt;Node&gt; next;
          std::shared_ptr&lt;Node&gt; previous;
      };
  
      class NullNode : public Node {
      public:
          virtual void setNext(Node* newNext) {};
          virtual void setPrevious(Node* newPrevious) {};
      };
  </code></pre>
  
  <p>node.cpp</p>
  
  <pre><code>    #include "node.h"
  
      std::shared_ptr&lt;Node&gt; Node::getNext() {
          if (nullptr == next) {
              return std::shared_ptr&lt;Node&gt;(new NullNode);
          }
          return next;
      }
  
      void Node::setNext(std::shared_ptr&lt;Node&gt; newNext) {
          next = newNext;
      }
  
      std::shared_ptr&lt;Node&gt; Node::getPrevious() {
          if (nullptr == previous) {
              return std::shared_ptr&lt;Node&gt;(new NullNode);
          }
          return previous;
      }
  
      void Node::setPrevious(std::shared_ptr&lt;Node&gt; newPrevious) {
          previous = newPrevious;
      }
  </code></pre>
  
  <p>main.cpp</p>
  
  <pre><code>    #include "linkedlist.h"
  
      void addToList() {
          LinkedList list;
          for (int i = 0; i &lt; 100; ++i) {
              list.addNode(i);
          }
          for (int i = 99; i &gt;= 0; ++i) {
              list.removeNode(i);
          }
      }
  
      int main() {
          addToList();
      }
  </code></pre>
  
  <p>I want to understand where did I go wrong - is it with the return of the shared_ptr's,</p>
  
  <p>is it the choice of the shared_ptr against weak / unique ?</p>
  
  <p>And of course - how do I make this code sample work properly .</p>