Использование shared_ptr с объектами - PullRequest
0 голосов
/ 02 октября 2018

У меня есть структура с именем Board.В этой структуре у меня есть атрибут с именем parentBoard, который должен просто указывать на другой объект Board.Первоначально я собирался использовать обычные указатели для этого, но я нашел что-то в stl для shared_pointers.Если я определю shared_ptr следующим образом: shared_ptr<Board> pointerToParentBoard;, как я могу сделать эту точку для уже определенного Board объекта?

Я уже пробовал это, надеясь, что это было похоже на обычный указатель:

pointerToNewBoard = &board1;

Но, увы, это не так, и я не могу найти что-нибудь в Google, чтобы помочь.Любая помощь очень ценится!

РЕДАКТИРОВАТЬ: В моем проекте утечки памяти являются очень дорогостоящими, и может быть трудно отслеживать всю выделенную память, поэтому я хочу использовать умные указатели.

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Избегайте использования сырых указателей в c ++, чтобы избежать случайных утечек памяти.Чтобы избежать циклической ссылки, используйте std :: weak_ptr для родительского элемента.

struct Board
{
private:
    std::weak_ptr<Board> _parent;

public:
    Board(std::shared_ptr<Board> parent = nullptr) {
        _parent = parent;
    }

    std::shared_ptr<Board> getParent() {
        std::shared_ptr<Board> strong = std::shared_ptr<Board>(_parent);
        return strong ? strong : nullptr;
    }

    std::shared_ptr<Board> traverseToRoot() {
        std::shared_ptr<Board> grand_parent = getParent();
        std::shared_ptr<Board> parent = grand_parent;
        while (!grand_parent) {
            parent = grand_parent;
            grand_parent = grand_parent->getParent();
        }
        return parent;
    }
};

int main()
{
    std::shared_ptr<Board> greatgrandparent = make_shared <Board>();
    std::shared_ptr<Board> grandparent = make_shared <Board>(greatgrandparent);
    std::shared_ptr<Board> parent = make_shared <Board>(grandparent);
    auto great_great_grand_parent = parent->traverseToRoot();
}
0 голосов
/ 02 октября 2018

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

struct Board
{
   private:
   std::shared_pointer<std::vector<Board>> children;
   Board * parent;
   public:
   Board(Board * ptr=nullptr):children(std::make_shared<std::vector<Board>>())
   {
        // don't add here, it becomes recursive
        parent = ptr;
   }

   // or add here
   Board addNew()
   {
       children->push_back(Board(this));
       return children->back();
   }

   // or add here
   void add(Board * ptr)
   {
       children->push_back(*ptr);
   }

   // make parent
   // should only use if "this" is a root node
   void makeParent(Board * b)
   {
       b.add(this);
       if(nullptr==parent)
           parent = b;
       else
           throw std::runtime_error("This node is not root. Can't change parent.");
   }

}

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

Также не забудьте добавить конструкторы для правила три / пять.

...