2011-01-29 28 views
0

與智能指針練習,看它們如何能夠防止內存泄漏,並通過RAII輔助內存管理,我做了以下內容:升壓智能指針和非POD類型(C++)

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

#include <iostream> 

using std::cout; 
using boost::shared_ptr; 

class myobj { 
    public: 
    shared_ptr<int> a; 
    myobj() { 
     shared_ptr<int> b(new int[50]); 
     a = b; 
    } 
    ~myobj() {} 
}; 

typedef boost::shared_ptr<myobj> myobj_ptr; 

int main() { 
    for (unsigned int i=0; i < 5000000; i++) { 
     myobj *foo = new myobj(); 
     myobj *bar = new myobj(); 
     myobj_ptr bar_ptr(bar); 

     bar_ptr = myobj_ptr(foo); 
     bar = foo; 
    } 
    return 0; 
} 

有什麼我不可能與此類似(希望我的目標遇到的「僞」代碼):

a = new int[50]; 

我明白爲什麼這不會從升壓shared_ptr.hpp文件本身的工作,但我不不明白爲什麼這不起作用:

shared_ptr<int> a; 
int *b; 
myobj() { 
    b = new int[50]; 
    boost::detail::sp_enable_shared_from_this(a, b, b); 
} 

它返回此錯誤:

warning: cannot pass objects of non-POD type ‘class boost::shared_ptr<int>’ through ‘...’; call will abort at runtime 

我不明白究竟。

回答

3

首先,boost::detail中的任何內容都是實現細節。除非你正在開發代碼,它本身就是提升的一部分,否則不要碰它。第二,boost::shared_ptr不能直接包裝數組。這是因爲C++中的數組必須用delete []刪除,而boost::shared_ptrdelete刪除。改爲使用boost::shared_array,或使用boost::shared_ptr改爲std::vector。如果你真的必須使用shared_ptr有一個數組,你必須使用定製刪除創建它:

template <typename T> 
struct array_deleter { 
    void operator()(T *p) { 
    delete [] p; 
    } 
}; 

// later... 
boost::shared_ptr<int> p(new int[50], array_deleter<int>()); 

請不要真正做到這一點,但是。使用shared_array<int>shared_ptr<vector<int> >

至於爲什麼你不能只是做:

boost::shared_ptr<int> a; 
// later 
a = new int; 

這是因爲這將是危險的,使它很容易使一些一個shared_ptr - 記住,如果你做的東西一個shared_ptr兩次,你最終會雙倍釋放它。所以shared_ptrs只會通過構造函數獲取原始指針。如果你確實要覆蓋一個shared_ptr與原始指針,這裏有一個方法:

a.swap(boost::shared_ptr<int>(new int)); 

這將創建一個新的指針,然後用a交換它。臨時智能指針(與a的舊值)然後被釋放。

+0

@丹尼爾,我已經加了一點,我認爲你的原意更密切。 – bdonlan 2011-01-29 11:17:14

2

除非您還提供執行delete[]而非delete的自定義刪除程序,否則不能將使用new int[50]分配的內容分配給shared_ptr<int>

enable_shared_from_this旨在增加類類型檢索擁有共享指針的能力,您只需從detail命名空間中提取某些內容即可。這不是爲了直接使用而設計的。它的設計就是這樣使用的。

class myobj : public boost::enable_shared_from_this<myobj> 
{ //... 

爲陣列的最簡單的管理容器將是std::vector<int>,不shared_ptr

+0

謝謝,我現在明白爲什麼shared_ptr不會支持新的int [50]。 但記住我只是在做這個練習智能指針,我已經明白這不是存儲整數的實用方法。 – dcousens 2011-01-29 11:16:38

0

對於初學者來說,你調用該函數是在detail命名空間,這意味着它可能並不意味着可以直接調用。這可能與你的問題有關。

至於你得到的特定錯誤,那個錯誤通常意味着你試圖調用一個傳遞非POD參數的可變參數函數。在這種情況下,這是因爲boost::shared_ptr<int>不是POD類型。我認爲這與使用數組與原始指針無關;我認爲你只是用錯誤的參數來調用錯誤的函數。你的意思是使用boost::shared_from_this

+0

我不打算在任何可行的解決方案中使用它,我知道它是在引擎蓋下,很可能完全不合適,我只是試圖重新創建與shared_ptr的構造函數類似的條件。 – dcousens 2011-01-29 11:17:41