2010-11-23 89 views
0

我使用Boost库中的智能指针。假设我有此对象:C++:boost:按值传递参数

boost::shared_ptr<A> a(new A); 

a->fileName = "/temp"; 

在B类,我有:

bool open(A *a); 

private: boost::shared_ptr<A> myA; 

然后我声明对象B:

boost::shared_ptr<B> b(new B()); 

b->open(a.get()); 

bool B::open(A *a) 
{ 
    *B::myA = *a; 
} 

上面的示例是关于传递值参数之三。编译是好的,但是当我运行它,它给了这个错误:

/usr/local/include/boost/smart_ptr/shared_ptr.hpp:412: typename boost::detail::shared_ptr_traits<T>::reference boost::shared_ptr<T>::operator*() const [with T = NameSpaceABC::Common::A]: Assertion `px != 0' failed. 
Aborted 

而对于上述同样的问题,我应该改变有什么:通过引用传递参数?由于我是C#和Java程序员,因此我只是为了一个快速项目而转向C++。我不熟悉使用指针和Boost智能指针。

在此先感谢,我非常感谢您的帮助!

+1

您是否尝试调试`VImageInputStream :: open`来查看`a`的`myA`是否为0? boost声明非常明确:您正在取消引用空的`shared_ptr`。 – icecrime 2010-11-23 09:59:25

+0

嗨,我已经检查了下面的Space_C0wb0y的答案。它工作正常,但我不确定它是否为值传递参数或引用传递参数?以及如何在智能指针的析构函数中写入'delete'。在此先感谢 – olidev 2010-11-23 10:08:13

回答

2

如果您对对象使用智能指针指针一次,则应始终对该对象使用它。在你的情况,open应该是这样的:

bool B::open(boost::shared_ptr<A> a) { 
    myA = a; 
} 

这样,你就必须传递给open对象引用的语义。你的代码示例试图分配对象,而不是引用。在这种情况下,你必须确保myA已经包含A类型的有效对象(最好是在构造函数):

B::B() : myA(boost::make_shared<A>()) {} 

然后,你可以写你的open方法是这样的:

bool B::open(const A & a) { 
    *myA = a; 
} 

另外,请阅读this以了解shared_ptr的工作原理。

0

您正在取消引用未指向对象的shared_ptr。

在我看来,可能有两种可能的情况。

1)您想分享main和B中的A对象。然后您应该传递一个shared_ptr来打开。

bool B::open(const shared_ptr<A>& a) 
{ 
    myA = a; 
} 

//called with 
b->open(a); 

2)你想B做一个值的副本。那么传递对象可能是有意义的。

bool B::open(const A& a) 
{ 
    myA.reset(new A(a)); 
} 

//called with 
b->open(*a); 

或许,如果myA已经指向一个对象,你会不会需要分配一个新的。

bool B::open(const A& a) 
{ 
    if (myA) 
     *myA = a; 
    else 
     myA.reset(new A(a)); 
}