数据结构是否是共享ptr的合适位置? 我在C++中实现了一个二叉树。传统上,我会有一个指向左边的指针和一个指向右边的指针,但手动内存管理通常以眼泪结束。这就引出了我的问题

数据结构是否是共享ptr的合适位置? 我在C++中实现了一个二叉树。传统上,我会有一个指向左边的指针和一个指向右边的指针,但手动内存管理通常以眼泪结束。这就引出了我的问题,c++,data-structures,shared-ptr,tr1,C++,Data Structures,Shared Ptr,Tr1,数据结构是使用共享ptr的合适位置吗?是的,绝对是 但是,如果您有一个循环数据结构,请小心。如果您有两个对象,它们都彼此具有共享ptr,那么如果不手动清除共享ptr,它们将永远不会被释放。在这种情况下,可以使用弱ptr。这当然不是二叉树的问题。共享的ptr会有一些额外的开销,特别是在空间需求方面,但是如果您的元素是单独分配的,那么共享的ptr将是完美的。在每个对象都有一个所有者的情况下,手动编写内存管理并不是那么困难,因此可以删除它在析构函数中拥有的内容 根据定义,一棵树由节点组成,每个节点都有

数据结构是使用共享ptr的合适位置吗?

是的,绝对是


但是,如果您有一个循环数据结构,请小心。如果您有两个对象,它们都彼此具有共享ptr,那么如果不手动清除共享ptr,它们将永远不会被释放。在这种情况下,可以使用弱ptr。这当然不是二叉树的问题。

共享的ptr会有一些额外的开销,特别是在空间需求方面,但是如果您的元素是单独分配的,那么共享的ptr将是完美的。

在每个对象都有一个所有者的情况下,手动编写内存管理并不是那么困难,因此可以删除它在析构函数中拥有的内容

根据定义,一棵树由节点组成,每个节点都有一个父节点,因此显然是它们的单一所有者的候选节点,因此这是一个非常愉快的时刻。恭喜你

我认为在您的案例中开发这样一个解决方案是非常值得的,同时尝试
shared_ptr
方法,将差异完全隐藏在一个相同的接口后面,因此您可以在两者之间切换,并将性能差异与一些实际的实验进行比较。这是唯一确定
共享\u ptr
是否适合您的应用程序的方法


(*对我们来说,如果你告诉我们如何进行。)

我认为这取决于你在哪里使用它们。我假设你想做的事情是这样的:

template <class T>
class BinaryTreeNode 
{
    //public interface ignored for this example
    private:
        shared_ptr<BinaryTreeNode<T> > left;
        shared_ptr<BinaryTreeNode<T> > right;
        T data;
}
template <class T>
class BinaryTreeNode 
{
    //public interface ignored for this example
    private:
        auto_ptr<BinaryTreeNode<T> > left;
        auto_ptr<BinaryTreeNode<T> > right;
        T data;
}
模板
二元树烯类
{
//本例中忽略了公共接口
私人:
共享_ptr左;
共享ptr权;
T数据;
}
如果您希望数据结构能够处理动态创建的节点,那么这将非常有意义。然而,由于这不是正常的设计,我认为这是不合适的

我的答案是,不,这不是一个使用shared_ptr的合适地方,因为shared_ptr的使用意味着对象实际上是共享的——但是,二叉树中的节点永远不会共享。然而,正如马丁·约克所指出的,为什么要重新发明轮子呢?已经有了一种智能指针类型,它可以实现我们正在尝试的功能——auto_ptr。那么就这样说吧:

template <class T>
class BinaryTreeNode 
{
    //public interface ignored for this example
    private:
        shared_ptr<BinaryTreeNode<T> > left;
        shared_ptr<BinaryTreeNode<T> > right;
        T data;
}
template <class T>
class BinaryTreeNode 
{
    //public interface ignored for this example
    private:
        auto_ptr<BinaryTreeNode<T> > left;
        auto_ptr<BinaryTreeNode<T> > right;
        T data;
}
模板
二元树烯类
{
//本例中忽略了公共接口
私人:
自动左上;
自动对位;
T数据;
}

如果有人问为什么数据不是共享的\u ptr,答案很简单——如果数据的副本对库的客户机有利,他们会传入数据项,树节点会生成一个副本。如果客户端认为复制是个坏主意,那么客户端代码可以传入一个共享的\u ptr,树节点可以安全地复制它。

因为左侧和右侧不共享boost::shared \u ptr可能不是正确的智能指针


这将是一个尝试std::auto_ptr的好地方,你甚至需要指针吗?您似乎可以使用
boost::可选的左、右

切勿对数据结构的节点使用共享ptr。如果在任何一点上共享了所有权,则会导致暂停或延迟节点的销毁。这可能导致以错误的顺序调用析构函数。
在数据结构中,节点的构造函数包含与其他节点耦合的任何代码,析构函数包含与其他节点解耦合的代码是一种很好的做法。按错误顺序调用的析构函数可能会破坏此设计。

树显然不是循环的。为什么不自动执行?您遗漏的公共界面。现在不可避免地需要包含一些内存管理的代码。这就是为什么我们有智能指针,所以我们不需要重新发明轮子来进行内存管理。好的,auto_ptr对他们来说是一个有效的选项-事实上,可能更好,因为它的语义与二叉树节点的左指针和右指针的语义一致。可能希望将类型t传播到左指针和右指针的声明上,否则将无法编译。