2012-07-02 59 views
12

我試着寫這個類奇怪的行爲,2010

#include <memory> 

class ContainerUnique 
{ 
public: 

    ContainerUnique(void); 
    ~ContainerUnique(void); 

private: 
    std::unique_ptr<UniqueElement> u; 
}; 

哪裏UniqueElement是別處定義的POD類。我現在定義這樣的構造函數體:

ContainerUnique::ContainerUnique(void) 
{ 
    auto tmp = new UniqueElement(1); 

    this->u(tmp); // u is a unique_ptr<UniqueElement>. Should this call compile? 
} 

而且它沒有例外。運行程序我發現在調用ContainerUnique的構造函數之後,u包含一個空指針。

這是預期的行爲?而且我真的在調用什麼unique_ptr方法?

+3

不確定你遇到的問題。但通過在構造函數的初始化列表中初始化成員變量u來避免它們。 –

+0

是的,這是我在真實代碼中使用的解決方案,但我仍然不確定該示例中發生了什麼。 –

+0

嘗試打印您的自動變量的類型。不知道typeid是否工作。一旦你知道這個類型,其他的應該很簡單。 –

回答

19

This is a known problem with VS2010's unique_ptr.來完成它從它的缺失者公開繼承,如果它是空的,因爲優化(空基優化)。公共繼承的缺點是,刪除者的所有成員也都成爲unique_ptr的可用成員,在這種情況下,它的operator()(T*)會刪除指針。

該錯誤在VS2012的庫中被修復,繼承被改爲私有。

+1

啊,你打我吧。很好的發現。 – stijn

2

應該像

ContainerUnique::ContainerUnique(void):u(new UniqueElement(1)) { 
} 
+1

這是我在生產代碼中解決問題的方式,但我仍然不確定示例中發生了什麼。 –

8

您打電話給default_delete<UniqueElement>::operator() (UniqueElement* ptr),因爲uniqe_ptr從中派生(從空基類優化中受益),並刪除ptr。這不完全是你想要的行爲,雖然我不認爲這個標準禁止它。