2014-04-12 4 views
-1

Я пытаюсь использовать некоторые новые методы проектирования для реализации связанного списка,C++ 11 Правильное использование интеллектуальных указателей в дважды связанный список

, но я не могу показаться, чтобы выяснить, только правильный путь к сделай это .

Методы - это умные указатели и шаблон нулевого объекта.

Проблемы, которые я имею в с разрушением всего списка,

У меня была одна реализация, где она не разрушится несколько объектов,

теперь я, кажется, имеют циклическую проблему и ее не выходит вообще.

Следит код:

linkedlist.h

#pragma once 
    #include <memory> 
    #include "node.h" 

    class LinkedList { 
    public: 
     LinkedList() : m_size(0), head(nullptr) {}; 
     void addNode(int value); 
     void removeNode(int index); 
    private: 
     std::shared_ptr<Node> getNodeAtIndex(int index); 
     std::shared_ptr<Node> getLastNode(); 
     void _addNode(int value); 
     inline void increaseSize() { ++m_size; } 
     inline void decreaseSize() { --m_size; } 
    private: 
     size_t m_size; 
     std::shared_ptr<Node> head; 
    }; 

linkedlist.cpp

#include "linkedlist.h" 

    void LinkedList::addNode(int value) { 
     _addNode(value); 
     increaseSize(); 
    } 

    void LinkedList::_addNode(int value) { 
     if (nullptr == head) { 
      head = std::make_shared<Node>(Node(value)); 
      return; 
     } 
     std::shared_ptr<Node> tail = getLastNode(); 
     std::shared_ptr<Node> nextNode = std::make_shared<Node>(Node(value)); 
     nextNode->setPrevious(tail); 
     tail->setNext(nextNode); 
    } 

    void LinkedList::removeNode(int index) { 
     std::shared_ptr<Node> node = getNodeAtIndex(index); 
     node->getNext()->setPrevious(node->getPrevious()); 
     node->getPrevious()->setNext(node->getNext()); 
     decreaseSize(); 
    } 

    std::shared_ptr<Node> LinkedList::getNodeAtIndex(int index) { 
     std::shared_ptr<Node> node = head; 
     for (int i = 0; i < index; ++i) { 
      node = node->getNext(); 
     } 
     return node; 
    } 

    std::shared_ptr<Node> LinkedList::getLastNode() { 
     return getNodeAtIndex(m_size-1); 
    } 

node.h

#pragma once 
    #include <memory> 

    class Node { 
    public: 
     Node() : value(0), next(nullptr), previous(nullptr) {}; 
     Node(int value) : value(value) {}; 
     ~Node() { printf("%d", value); }; 
     std::shared_ptr<Node> getNext(); 
     virtual void setNext(std::shared_ptr<Node> newNext); 
     std::shared_ptr<Node> getPrevious(); 
     virtual void setPrevious(std::shared_ptr<Node> newPrevious); 
    private: 
     int value; 
     std::shared_ptr<Node> next; 
     std::shared_ptr<Node> previous; 
    }; 

    class NullNode : public Node { 
    public: 
     virtual void setNext(Node* newNext) {}; 
     virtual void setPrevious(Node* newPrevious) {}; 
    }; 

node.cpp

#include "node.h" 

    std::shared_ptr<Node> Node::getNext() { 
     if (nullptr == next) { 
      return std::shared_ptr<Node>(new NullNode); 
     } 
     return next; 
    } 

    void Node::setNext(std::shared_ptr<Node> newNext) { 
     next = newNext; 
    } 

    std::shared_ptr<Node> Node::getPrevious() { 
     if (nullptr == previous) { 
      return std::shared_ptr<Node>(new NullNode); 
     } 
     return previous; 
    } 

    void Node::setPrevious(std::shared_ptr<Node> newPrevious) { 
     previous = newPrevious; 
    } 

main.cpp

#include "linkedlist.h" 

    void addToList() { 
     LinkedList list; 
     for (int i = 0; i < 100; ++i) { 
      list.addNode(i); 
     } 
     for (int i = 99; i >= 0; ++i) { 
      list.removeNode(i); 
     } 
    } 

    int main() { 
     addToList(); 
    } 

Я хочу, чтобы понять, где я ошибся - это с возвращением shared_ptr лет,

является его выбором shared_ptr против слабого/уникального ?

И, конечно же, как я могу сделать этот образец кода правильно.

ответ

2
for (int i = 99; i >= 0; ++i) { 
    list.removeNode(i); 
} 

Когда i начинается как 99 и вы только добавить к нему (++i), плохие вещи, вероятно, будет происходить до того, как переливается. Вероятно, вы имели в виду --i.

Вы должны рассмотреть писать его, как это вместо:

for (int i = 0; i < 100; ++i) { 
    list.removeNode(0); 
} 

Или:

while (!list.empty()) list.removeNode(0); 

Последний способ требует, чтобы выставить размер контейнера или добавить requsite empty() функцию, чтобы проверить, если список пуст.


Если вы запустили программу в отладчике, это помогло бы вам обнаружить эту проблему самостоятельно. Вы должны научиться использовать отладчик :)

Смежные вопросы