Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在指针到指针场景中使用std::shared_ptr_C++_Shared Ptr_C++17_Smart Pointers - Fatal编程技术网

C++ 在指针到指针场景中使用std::shared_ptr

C++ 在指针到指针场景中使用std::shared_ptr,c++,shared-ptr,c++17,smart-pointers,C++,Shared Ptr,C++17,Smart Pointers,我创建了一个节点结构,用于二进制搜索树的实现。它使用共享指针跟踪其子项: template <class T> struct Node; template <class T> using Node_ptr = std::shared_ptr<Node<T>>; template <class T> struct Node { Node_ptr<T> left; Node_ptr<T> right;

我创建了一个
节点
结构,用于二进制搜索树的实现。它使用共享指针跟踪其子项:

template <class T> struct Node;

template <class T>
using Node_ptr = std::shared_ptr<Node<T>>;

template <class T>
struct Node {
  Node_ptr<T> left;
  Node_ptr<T> right;
  const T label;
  ...
};
很糟糕。但它是有效的:

template <class T>
class Binary_search_tree {
public:
  // correctly inserts consecutive values
  void insert(const T& value) {
    if (auto* node = find_node(&root, value); !*node)
      *node = std::make_shared<Node<T>>(value);
  }
  ...
private:
  Node_ptr<T> root;
  ...
};
  • 当您必须允许传递空指针时,建议使用原始指针-在您的示例中不是true;或者当您必须传递非整数值时(在您的情况下为true)。在后一种情况下,仍然应该考虑传递引用而不是原始指针。这是一个一般性建议,因此可能存在例外情况

  • 注意到了这一点,通过将find_node(…)设置为私有函数,同时保持insert(…)为公共函数,您仍然可以在函数中安全地使用原始指针。这是安全的,因为不可能让指针从insert(…)内部悬空

  • 本质上,我们需要防止两种可能的原始指针:#1。过早删除指针指向的内存#2。永远不要删除指针指向的内存。在insert(…)函数中,这两种方法都不可能实现。所以你很安全


    在一个相关的注释中,您可以考虑在创建节点时使用UNIQuyPyPosik,如果它们要被多个子对象共享,则将它们转换成共享指针:STD::St迁(…).< /P>因为您没有直接分配<代码> NoDEYPPT**/COD> >您所做的可能看起来“相当糟糕”,但它也是有效的,在这种情况下,我看不出有任何理由将共享指针围绕在共享指针周围。如果您一直在分配和存储指向共享指针的指针,这将改变一切。所有这些都说明了,您为什么不使用引用返回类型?我认为在您演示的情况下,

    节点
    决不会为空。事实上,传递的
    节点
    也将是一个参考候选。您真的需要这里的
    共享\u ptr
    ?你在不同的树之间共享节点吗?@WhozCraig谢谢!实际上,起始节点和返回节点都可以通过引用传递。我完全忽略了这个事实,更关注函数的主体。但正如您所指出的,在那里使用原始指针的方式中,它们不会带来通常与之相关的风险。也许我挖得太深了:)如果你不在树之间共享笔记,或者不允许在一棵树中多次插入同一个节点,那么你只能在一种情况下(节点删除)从智能指针中获益,而在所有其他情况下,你会有相当大的开销(插入、移动节点,例如用于树平衡…)因为除了修改树(所有涉及的节点都已知…)之外,您实际上不会共享指针。所以可能
    std::unique_ptr
    是更好的选择?
    template <class T>
    class Binary_search_tree {
    public:
      // correctly inserts consecutive values
      void insert(const T& value) {
        if (auto* node = find_node(&root, value); !*node)
          *node = std::make_shared<Node<T>>(value);
      }
      ...
    private:
      Node_ptr<T> root;
      ...
    };
    
    template <class T>
    Node_ptr<T>& find_node(Node_ptr<T>& node_ref, const T& value) {
      auto* node = &node_ref;
      ...
      return *node;
    }