2012-09-07 48 views
12

簡單問題:你允許明確刪除boost::shared_ptr自己嗎?你應該嗎?這裏明確刪除一個shared_ptr

澄清,我不是指刪除由shared_ptr舉行的指針。我的意思是實際的shared_ptr本身。我知道大多數人建議不這樣做,所以我只是想知道是否明確地做到這一點。

+1

當然,你被允許刪除(動態分配)* *的shared_ptr;刪除它的內容是完全不同的問題;-) –

+0

我認爲你正在尋找'weak_ptr'。 – ybungalobill

+5

動態分配'shared_ptr'失敗使用'shared_ptr'的目的。 – Dan

回答

2

您不能強制其引用計數爲零,否。

想想那些工作需要什麼。你需要去使用shared_ptr的每個地方並清除它。

如果沒有強制共享指針刪除,並將其設置爲NULL,這將是就像一個weak_ptr的。但是,使用該shared_ptr的代碼中的所有位置都沒有準備好,並且希望持有有效的指針。他們沒有理由檢查NULL,所以這些代碼會崩潰。

23

你的問題不清楚。如果您已動態分配shared_ptr,那麼您無論何時都可以隨時撥打delete

但如果你詢問你是否要允許刪除任何對象正在由shared_ptr管理,那麼答案是...它依賴。如果shared_ptr::unique返回true,則調用shared_ptr::reset將刪除管理對象。但是,如果shared_ptr::unique返回false,則表示共享該對象的所有權不止一個shared_ptr。在這種情況下reset呼叫只會造成1被遞減引用計數,對象的實際刪除將發生在最後一個shared_ptr管理該對象或者超出範圍或者其本身就是reset

編輯:
編輯後,似乎你問的是刪除動態分配的shared_ptr。這樣的事情:

auto sp = new boost::shared_ptr<int>(new int(42)); 

// do something with sp 

delete sp; 

這是允許的,並將按預期工作,雖然這將是一個不尋常的用例。唯一需要注意的是,如果在sp分配和刪除之間創建另一個shared_ptr共享對象的所有權,刪除sp不會導致對象的刪除,只會當對象的引用計數爲0發生

4

[編輯:您可以delete a shared_ptr當且僅當它創建與new,與任何其他類型相同。我想不出爲什麼你會創建一個newshared_ptr,但沒有什麼能阻止你。]

好了,你可以delete ptr.get();

這樣做會導致幾乎不可避免地不確定的行爲既可以當其他共享業主使用他們的shared_ptr訪問現已刪除的對象,或最後shared_ptr對象被破壞,並且對象被再次刪除。

所以不,你不應該。

shared_ptr的目的是管理的對象,沒有一個「人」有刪除的權利或責任,因爲可能有其他人共享所有權。所以你也不應該想要。

1

如果要模擬計數減量,你可以做手工在堆上像這樣:

int main(void) { 
    std::shared_ptr<std::string>* sp = new std::shared_ptr<std::string>(std::make_shared<std::string>(std::string("test"))); 
    std::shared_ptr<std::string>* sp2 = new std::shared_ptr<std::string>(*sp); 
    delete sp; 

    std::cout << *(*sp2) << std::endl; // test 
    return 0; 
} 

或者在棧上使用std::shared_ptr::reset()像這樣:

int main(void) { 
    std::shared_ptr<std::string> p = std::make_shared<std::string>(std::string("test")); 
    std::shared_ptr<std::string> p2 = p; 
    p.reset(); 

    std::cout << *p2 << std::endl; // test 
    return 0; 
} 

但它不是這很有用。

0

Expliticly刪除就派上用場了一些(很?)罕見的情況下。

除了明確刪除,有時你必須明確地破壞一個共享指針,當你是「刪除」吧!與C代碼接口時,路過一個shared_ptr作爲一個不透明的價值

東西可以得到奇怪的。

例如,對於經過的物體,並從其中被寫入C. Lua腳本語言(www.lua.org)我有以下

static void push(lua_State *L, std::shared_ptr<T> sp) 
{ 
    if(sp == nullptr) { 
     lua_pushnil(L); 
     return; 
    } 

    // This is basically malloc from C++ point of view. 
    void *ud = lua_newuserdata(L, sizeof(std::shared_ptr<T>)); 

    // Copy constructor, bumps ref count. 
    new(ud) std::shared_ptr<T>(sp); 

    luaL_setmetatable(L, B::class_name); 
} 

所以這就是在一些malloc分配存儲器一個shared_ptr 。相反的是...(設置在Lua垃圾收集對象之前被調用,並且是免費的)。

static int destroy(lua_State *L) 
{ 
    // Grab opaque pointer 
    void* ud = luaL_checkudata(L, 1, B::class_name); 

    std::shared_ptr<T> *sp = static_cast<std::shared_ptr<T>*>(ud); 

    // Explicitly called, as this was 'placement new'd 
    // Decrements the ref count 
    sp->~shared_ptr(); 

    return 0; 
} 
相關問題