2010-05-03 20 views
2

我記得以前遇到過這個概念,但現在在Google找不到。如何將boost :: shared_ptr(或另一個智能指針)附加到對象父級的引用計數器?

如果我有類型A的一個對象,它直接嵌入B型的一個目的:

class A { 
    B b; 
}; 

怎樣纔可以有一個智能指針到B,例如G。 boost::shared_ptr<B>,但使用引用計數A?假設A本身是一個實例堆分配,我可以安全地使用它的共享計數,例如enable_shared_from_this

+0

爲什麼你想這樣做嗎? – 2010-05-03 01:24:22

+0

@Marcelo Cantos,例子是通過TCP連接的消息處理:從套接字讀取需要提供連續的緩衝區,但是您希望能夠對離散消息進行操作(對它們進行排隊並傳遞給它們)。因此,您可以創建額外的消息副本(佔用兩倍的內存,可能會導致分段),或者可以在每條消息的shared_ptr(如果每個消息都是POD並直接映射到緩衝區中的某個點)中對緩衝區進行重新計數。這樣,當最後一條消息的shared_ptr被銷燬時,緩衝區將被刪除(或返回到池等)。 – 2010-05-03 04:18:07

+0

PS也就是說,如果由於需要成爲POD類型而無法將消息中的shared_ptr保存到消息中。 – 2010-05-03 04:27:25

回答

5

D'oh!

shared_ptr文檔中發現它正確。它被稱爲別名(參見section III of shared_ptr improvements for C++0x)。

我只需要使用不同的構造函數(或相應的reset函數重載):

template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p); 

哪像這樣的作品(你需要先建立shared_ptr的母公司):

#include <boost/shared_ptr.hpp> 
#include <iostream> 

struct A { 
    A() : i_(13) {} 
    int i_; 
}; 

struct B { 
    A a_; 
    ~B() { std::cout << "B deleted" << std::endl; } 
}; 

int 
main() { 
    boost::shared_ptr<A> a; 

    { 
     boost::shared_ptr<B> b(new B); 
     a = boost::shared_ptr<A>(b, &b->a_); 
     std::cout << "ref count = " << a.use_count() << std::endl; 
    } 
    std::cout << "ref count = " << a.use_count() << std::endl; 
    std::cout << a->i_ << std::endl; 
} 
+0

我從來不知道別名 - 謝謝你的提示 – 2012-04-17 18:54:40

+0

@StephenNutt即使將'shared_ptr'轉換爲派生類到基類,也會涉及別名。 – curiousguy 2017-01-23 21:47:28

1

我還沒有測試過這個,但你應該可以使用custom deallocator object來保持一個shared_ptr到父母身邊,只要孩子仍然需要。沿着這些線:

template<typename Parent, typename Child> 
class Guard { 
private: 
    boost::shared_ptr<Parent> *parent; 
public: 
    explicit Guard(const boost::shared_ptr<Parent> a_parent) { 
     // Save one shared_ptr to parent (in this guard object and all it's copies) 
     // This keeps the parent alive. 
     parent = new boost::shared_ptr<Parent>(a_parent); 
    } 
    void operator()(Child *child) { 
     // The smart pointer says to "delete" the child, so delete the shared_ptr 
     // to parent. As far as we are concerned, the parent can die now. 
     delete parent; 
    } 
}; 

// ... 

boost::shared_ptr<A> par; 
boost::shared_ptr<B> ch(&par->b, Guard<A, B>(par)); 
相關問題