2010-11-23 57 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)); 
}