我应该在通用二叉搜索树中为根使用什么类型的指针?

时间:2018-02-10 23:48:37

标签: c++

这是我的通用二叉搜索树的标题。现在我只是使用原始指针作为树的根。我应该使用什么样的指针?一些类型是唯一的,共享的,(智能指针)弱,原始和开启。 。 。 。

template <typename T>
class BST
{
public:
    BST();
    BSTNode<T>* Root;
    void Insert(BSTNode<T> newNode);
    void Delete(T deleteNode);
    BSTNode<T>* ReturnNodeSearch();
    BSTNode<T>* MinimumValue();
    BSTNode<T>* MaximumValue();
    bool isEmpty();
};

3 个答案:

答案 0 :(得分:2)

使用std::unique_ptr,因为非常您不太可能希望两个单独的BST个对象共享相同的实现节点。通常,在这种情况下,您只需使用外部引用或(可能)外部std::shared_ptrBST对象本身。

答案 1 :(得分:0)

这取决于你想做什么。我建议最佳做法是使用std::unique_ptr<>std::shared_ptr<>来确保在不再需要时正确释放内存。但是,原始指针可以在这里工作,但您必须自己处理释放。一般来说,智能指针处理和拥有动态分配内存的好处往往超过使用原始指针的好处。

更详细但更高层次:

  • 原始指针 - 处理问题,但如果不再需要此内存,则只需管理释放。当某个其他对象仍有指向它的指针时,您可能会意外地释放一个对象/函数中的内存
  • std::unique_ptr<> - 将在其生命周期内管理内存,如果您不必与任何其他对象共享指针,那就太好了
  • std::shared_ptr<> - 也将管理内存,通过引用计算有多少std::shared_ptr<>也正在观察内存位置,从而增加了一些开销。这也将确保只有在没有其他std::shared_ptr<>对象指向它的情况下才会删除内存
  • std::weak_ptr<> - 只能与std::shared_ptr<>结合使用,用于防止内存中同一对象的引用周期

不一定是错误的答案。这取决于您期望的实施。您唯一不应使用的类型是std::auto_ptr<>,因此请避免使用该类型。

答案 2 :(得分:-2)

在查看代码示例时,可以想到3个选项,其中任何一个都是可行的选项;让我们在下面探讨这些选项。

  
      
  • Raw pointer
  •   
  • shared_ptr<T>
  •   
  • unique_ptr<T>
  •   

每个都有自己的缺点和优点。他们使用的优点。

由于您在示例中使用raw;我先从那个开始:

  

<强>原始

     
      
  • Pro: - 您可以灵活地管理自己的记忆,但这需要承担更高的责任。
  •   
  • Con: - 很容易出现内存泄漏,悬空等等。无效指针。
  •   
           

<强> shared_ptr的

     
      
  • Pro: - 为你管理记忆;并且可以跨多个对象访问,因为它是通过引用计数共享内存。
  •   
  • Con: - 这是基于这样一种假设,即你永远不会因为使用这个智能指针而面临内存泄漏或悬空指针,因为它并不总能保证释放,但通常最多案例。有时您可能不希望跨多个对象访问指针。它引用计数的性能也很小。
  •   
           

<强>的unique_ptr

     
      
  • Pro: - 与上述几乎完全相同,只有一个对象可以拥有此对象,从而为不必要的访问提供更多保护。
  •   
  • Con: - 在假设永远释放内存的情况下,与上述类似。如果所需的功能确实需要多个对象或源来在将来的某个时间点访问它,那么您将受限于使用这种类型的指针。您可以转让所有权,但无法通过多个对象进行访问。
  •   

最后,您可以根据自己的需要选择使用哪种类型。在你的特殊情况下,如果它们是private members,那么在类中使用原始指针没有任何问题,但是你需要更多的工作来管理这个类,而更多的是在处理分配时需要良心。释放记忆。如果使用unique_ptr,则知道内存对象是否严格地属于相关类对象的内部。如果使用shared_ptr,则需要知道哪些外部对象将引用它。

最后你问:

  

What kind of pointer should I use?

从上述信息中了解并了解您正在使用的对象的类型,让我们考虑一下BST做什么或负责什么以及它作为一个类对象的主要作用。

我们知道Binary Space Partitioning Tree通常与Binary Search一起使用。其中一个是data structure,另一个是searching algorithm

这是一棵树,由一组nodes组成,每个node都有2 leaf nodes。树中的第一个node通常称为roothead,其中没有数据或emptyterminating node的叶节点通常称为tail,通常设为nullnullptr。我们可以看到这些节点的关系,并且知道BST至少会有ownership节点root。这样,BST对象的每个实例都将与另一个实例不同。例如:

BST tree1; // Tree 1
BST tree2; // Tree 2

// Not valid code below but shown to illustrate a concept
tree1.root != tree2.root; // These two roots are not equal as in not the same memory.

我们希望保持一棵树与另一棵树不同,因为这种行为我们真的不想使用shared_ptr。如果不使用raw pointers并管理自己的内存并使用智能指针在ownership之间的多个对象之间显示uniquenessunique_ptr,我认为这个特定的类是更好的选择然后成为可供选择的人。

在设计课程并尝试决定使用哪些smart pointer这些是您应该问及的基本问题时。回答你自己:

  • 这个对象是have a吗?如是;它是单独拥有它还是每个实例的内存都需要是唯一的?如是;然后使用unique_ptr
  • 是否必须跨多个对象引用此对象?如果是,请使用shared_ptr

以下是一些参考文献:一篇来自论文,另一篇来自Q / A,一篇来自代码审查:

  

这些参考文献也可以帮助您做出明确的决定。