2015-10-14 5 views
1

Ошибка в функции insert и printTree. Я знаю, что эта ошибка вызвана уникальной функцией unique_ptr. Но я думал, что предоставление семантики перемещения и копирования поможет мне решить ее. Мои вопросыИспользование удаленной функции std :: unique_ptr

  1. ли я сделал копию и двигаться Конструкторы правильно?

  2. Если нет. Как мне перепроектировать код. Просьба указать основные ошибки и способы их устранения.

  3. Как я могу включить родительский узел Node * в класс?

  4. Несколько советов по передовой практике кода в таких случаях было бы полезно

    // This is implementation of binary search tree. 
    
        #ifndef BinarySearchTree_H 
    
        #define BinarySearchTree_H 
    
    
        #include <cstdio> 
        #include <functional> 
        #include <utility> 
        #include <vector> 
        #include <iostream> 
        #include <memory> 
    
        //template declaration 
        template <class ValueType> 
    
        class BinarySearchTree 
        { 
    
         struct Node 
         { 
          ValueType value; 
    
          std::unique_ptr<Node> left; 
          std::unique_ptr<Node> right; 
    
          //Node *parent=nullptr; // How can I use parent in the class ? 
    
          Node(){} 
    
          //Node(const ValueType& value,std::unique_ptr<Node> left,std::unique_ptr<Node> right):value(value),left(left),right(right){} 
    
          Node (const ValueType& value):value(value),left(nullptr),right(nullptr){} 
    
         }; 
    
         std::unique_ptr<Node> root; 
    
         void insert(const ValueType& value, std::unique_ptr<Node> node) 
         { 
          if(value< node->value) 
          { 
           if(node->left) 
           { 
            insert(value,node->left); 
           } 
    
           else 
           { 
            std::unique_ptr<Node> left=std::unique_ptr<Node>(new Node(value)); 
            node->left=left; 
           } 
    
          } 
    
          else 
          { 
           if(node->right) 
           { 
            insert(value,node->right); 
           } 
    
           else 
           { 
            std::unique_ptr<Node> right=std::unique_ptr<Node>(new Node(value)); 
            node->right=right; 
            //right->parent=node; 
           } 
          } 
         } 
    
         void printNode(std::unique_ptr<Node> node) 
         { 
          if(!node) 
          { 
           std::cout<<"No element in the tree\n"; 
          } 
          else 
          { 
           if(node->left) 
           { 
            std::cout<<node->left->value<<" "; 
           } 
           std::cout<<node->value<<" "; 
           if(node->right) 
           { 
            std::cout<<node->right->value<<" "; 
           } 
          } 
         } 
    
        public: 
    
         BinarySearchTree():root(nullptr){} 
         ~BinarySearchTree(){} 
    
         BinarySearchTree(BinarySearchTree && rhs):root(std::move(rhs.root)){} 
    
         BinarySearchTree& operator=(BinarySearchTree && rhs) 
         { 
          root=std::move(rhs.root); 
          return *this; 
         } 
    
         BinarySearchTree& operator=(const BinarySearchTree & rhs) 
         { 
          if(this!=&rhs) 
          root.reset(rhs.root); 
          return *this; 
         } 
    
         void insert(const ValueType& value) 
         { 
          if(root==nullptr) 
          { 
           root=std::unique_ptr<Node>(new Node(value)); 
    
          } 
    
          else 
          { 
           insert(value,root); 
          } 
         } 
         // void remove(const ValueTypr& value); 
    
         void printTree(const BinarySearchTree& tree) 
         { 
          if(tree.root) 
          { 
           if(tree.root->left) 
           { 
            printNode(tree.root->left); 
           } 
           printNode(tree.root); 
           if(tree.root->right) 
           { 
            printNode(tree.root->right); 
           } 
          } 
    
          else 
          { 
           std::cout<<"tree is empty\n"; 
           return; 
          } 
         } 
    
        }; 
    
    
    
        #endif // BinarySearchTree 
    
+1

Вы действительно не должны думать о новых умных указателях как указателях в старом «нормальном» способе, вместо этого вы должны думать о них больше как владение ресурсом: может ли ресурс иметь только одного владельца за раз ('std :: unique_ptr') или иметь много одновременных владельцев (' std :: shared_ptr')? –

+0

@JoachimPileborg. Я знаю, что unique_ptrs имеют только одно владение. Моя проблема связана с моей неспособностью построить семантику перемещения и копирования для BinaryTree. – AlexanderTG

+1

Извините за то, что, возможно, звучание невежливо, но какая часть «единого владения» заставляет думать, что вы * можете * реализовать любое копирование? Вы не можете скопировать объект 'std :: unique_ptr', вы не можете скопировать указатель внутри него (тогда у вас есть два объекта' std :: unique_ptr', содержащий один и тот же указатель, в то время как приведет к плохим вещам), единственное путь - фактически создать новые узлы и скопировать только значение. Возможно, вам придется переосмыслить свой дизайн или, по крайней мере, реализовать проект, который у вас есть. –

ответ

2
  1. Нет, вы не можете копировать уникальные указатели. Вы должны решить, являются ли глубокие копии вашего дерева значимыми или нет.
  2. Используйте конструктор move и переместите оператор присваивания вместо конструктора копирования и оператора присваивания копии.
  3. Добавить необработанный указатель Node* parent. Родитель владеет своими детьми, а не наоборот.
  4. Использование std::make_unique(). Избегайте включения заголовков, которые вам не нужны. Есть ли причина, почему printTree() не работает на this? Как правило, вы можете использовать немного более читаемый синтаксис (отступы, пустые строки и т. Д.)
+0

Ошибка в функции printTree, которую компилятор дает точкам для инициализации функции printNode. Ошибка, указывающая на этот «аргумент инициализации 1 из» void BinarySearchTree :: printNode (std :: unique_ptr :: Node>) [with ValueType = int] '| – AlexanderTG