如何使用 boost::shared_ptr 构造二叉树

Posted

技术标签:

【中文标题】如何使用 boost::shared_ptr 构造二叉树【英文标题】:How do I construct binary trees using boost::shared_ptr 【发布时间】:2013-01-02 01:17:04 【问题描述】:

我正在尝试使用 boost 共享指针来构造二叉树并将节点存储在 STL 映射中。我采用了一个常见的二叉树示例,并尝试将指针转换为 shared_ptr,如下所示。我可能让它变得比需要的更复杂,因为我认为使用模板是个好主意。

#include <iostream>
#include <string>
#include <map>
using namespace std;

#include "boost/smart_ptr.hpp"

//typedef boost::shared_ptr<node<int> >  nodePtr;

template <typename T>
class node

public:

    T nodeData;
    boost::shared_ptr<node<T> > *left, *right;

    // default constructor. data not initialized
    node() 

     // initialize the data members
    node (const T& item, 
          boost::shared_ptr<node<T> > lptr = NULL, 
          boost::shared_ptr<node<T> > rptr = NULL) :
          nodeValue(item), left(lptr), right(rptr) 
;

template <typename T>
void inorderOutput(boost::shared_ptr<node<T> > t)

   // the traversal terminates on a empty subtree
   if (t != NULL)
   
      inorderOutput(t->left);       // descend left
      cout << t->nodeData << ", ";  // output the node
      inorderOutput(t->right);      // descend right
   


int main()

    // a few nodes to assemble into a tree
    boost::shared_ptr<node<char> > d( new node<char>('D') );
    boost::shared_ptr<node<char> > e( new node<char>('E') );
    boost::shared_ptr<node<char> > f( new node<char>('F') );
    boost::shared_ptr<node<char> > g( new node<char>('G') );

    boost::shared_ptr<node<char> > b( new node<char>('B',d, e) );
    boost::shared_ptr<node<char> > c( new node<char>('C',f, g) );
    boost::shared_ptr<node<char> > a( new node<char>('A',b, c) );

    // now store the node pointers for later reference
    map<string, boost::shared_ptr<node<char> > > nodeMap;
    nodeMap["D"] = d;
    nodeMap["A"] = a;
    // etc.

    // inorder traversal of nodes  
    cout << "Inorder:      " ;
    inorderOutput(a);
    cout << endl;

    // Test to see if a node has children
    if (( nodeMap["A"]->left != NULL ) || (nodeMap["A"]->right != NULL ) ) 
    
        cout << "Node A has children!" << endl;
    

    return 0;

我在 Visual Studio Express 2010 中构建并收到以下错误:

1>  SharedPtr.vcxproj -> c:\users\john\documents\visual studio 2010\Projects\SharedPtr\Debug\SharedPtr1.exe
2>c:\users\john\documents\visual studio 2010\projects\sharedptr\sharedptr2\sharedptr2.cpp(27): error C2440: 'default argument' : cannot convert from 'int' to 'boost::shared_ptr<T>'
2>          with
2>          [
2>              T=node<char>
2>          ]
2>          No constructor could take the source type, or constructor overload resolution was ambiguous
2>c:\users\john\documents\visual studio 2010\projects\sharedptr\sharedptr2\sharedptr2.cpp(49): fatal error C1903: unable to recover from previous error(s); stopping compilation

显然节点构造函数没有正确定义。我一直在旋转我的***一段时间,试图找出我做错了什么(可能是几件事!)。另外,假设我可以编译它,节点子节点的测试是否可以工作?以前的实验让我有理由相信这并不容易。最后,我注释掉了列表顶部的 typdef,因为我也没有正确使用它。任何人都可以建议一种清理此代码的方法吗?

约翰

【问题讨论】:

为什么要保留指向shared_ptr 的指针?你清楚它们是如何工作的吗? 【参考方案1】:

改变

 node (const T& item, 
      boost::shared_ptr<node<T> > lptr = NULL, 
      boost::shared_ptr<node<T> > rptr = NULL) :
      nodeValue(item), left(lptr), right(rptr) 
 ;

 node (const T& item, 
      const boost::shared_ptr<node<T> >& lptr = boost::shared_ptr<node<T> >(), 
      const boost::shared_ptr<node<T> >& rptr = boost::shared_ptr<node<T> >()) :
      nodeValue(item), left(lptr), right(rptr) 
 ;

正如所指出的,将“左”和“右”设为非指针 boost_shared_ptr。

【讨论】:

【参考方案2】:

NULL 在大多数实现中会将我的 #defined 设为 0,看起来猜测 boost::shared_ptr 不知道如何处理它。

改变

boost::shared_ptr<node<T> > *left, *right;

boost::shared_ptr<node<T> > left, right;

node (const T& item, 
      boost::shared_ptr<node<T> > lptr = NULL, 
      boost::shared_ptr<node<T> > rptr = NULL) :

node (const T& item, 
      boost::shared_ptr<node<T> > lptr = boost::shared_ptr<node<T> >(), 
      boost::shared_ptr<node<T> > rptr = boost::shared_ptr<node<T> >()) :

【讨论】:

成功了,谢谢!我不确定我是否理解您对构造函数默认值所做的事情。 lptr = boost::shared_ptr >() 究竟是做什么的? @JohnSchroeder 用默认构造函数构造一个boost::shared_ptr,我猜它给出了一个空指针。 boost::shared_ptr&lt;node&lt;T&gt; &gt;() 本质上是对其构造函数的调用。

以上是关于如何使用 boost::shared_ptr 构造二叉树的主要内容,如果未能解决你的问题,请参考以下文章

boost::shared_ptr

boost::shared_ptr - 两个类之间的组合关系

如何使用 g++ 在 Linux 上使用 boost/shared_ptr.hpp 编译 c++ 程序

如何结合 boost::shared_ptr 和 stl 列表

使用 boost::shared_ptr 访问静态成员变量

boost: 使用自定义删除器序列化 shared_ptr