2012-06-21 53 views
4

我們有一個廣泛的代碼庫,目前使用原始指針,我希望能夠遷移到unique_ptr。但是,許多函數都將raw指針作爲參數,而unique_ptr不能用於這些情況。我意識到我可以使用get()方法來傳遞原始指針,但是這增加了我必須接觸的代碼行數,並且我覺得它有點不雅觀。我滾我自己的unique_ptr看起來像這樣:在unique_ptr上有一個演員操作符是否危險?

template <class T> 
class my_unique_ptr: public unique_ptr <T> 
{ 
    public: 

    operator T*() { return get(); }; 
}; 

每當我到一個功能PARM一個希望將原始指針提供my_unique_ptr時,它自動地把它變成原始指針。

問題:這樣做有什麼固有的危險嗎?我原以爲這是unique_ptr實現的一部分,所以我假設它的省略是故意的 - 有誰知道爲什麼?

+0

好吧,你可以試試'cout << my_unique_ptr ()<< endl;' –

+1

一般來說,隱式轉換是不好的。類型的存在是有原因的,轉換應該是明確的。 – GManNickG

+1

@GManNickG:只要他們知道那個時候,裏奇定義了內建類型之間的隱含轉換。 –

回答

4

這與調用​​上的get相同,但它會自動完成。您必須確保指針在函數返回後未被存儲/使用(因爲​​將在其生命週期結束時將其刪除)。

另外請確保您不要在原始指針上調用delete(即使間接)。

還有另一件事,以確保爲您不要創建另一個智能指針,是以指針的所有權(如另一uniqe_ptr<>) - 見刪除上面

的原因音符爲​​沒有做轉換爲你自動地(並且你明確地呼叫get())是爲了確保你能夠控制你何時訪問原始指針(以避免上述可能以其他方式靜默發生的問題)

+3

如果沒有別的,缺乏轉換可以防止新手的災難(new int());刪除;從編譯:-)我不能立即想到任何非新手錯誤的情況下,有人會錯誤地刪除一個指針,其資源,他們不擁有,以及需要調用'get( )'阻止他們這樣做。 –

7

在事故中有很多醜陋的事情發生隱式轉換,例如:

std::unique_ptr<resource> grab_resource() 
{return std::unique_ptr<resource>(new resource());} 

int main() { 
    resource* ptr = grab_resource(); //compiles just fine, no problem 
    ptr->thing(); //except the resource has been deallocated before this line 
    return 0; //This program has undefined behavior. 
} 
+0

哇,我沒想到這是最受歡迎的答案,因爲其他人有很好的描述。 –

1

在unique_ptr上有一個演員操作符是危險的嗎?

編輯看評論

---不,這當然應該不會有危險---: 事實上的標準需要 explicit轉換爲「安全布爾'(見Safe Bool Idiom)。

說明用於編輯:

新標準(也引入的unique_ptr)引入explicit operator T()轉換。它仍然適用於unique_ptr 好像它是一個隱式轉換,因爲if,while,for(;x;)確實自動上下文轉換爲bool。

在我的防守,我的知識主要是基於C++ 03庫like Boost which do定義轉換unspecified-bool-typeimplicit

我希望這仍然是其他人的信息。


(見其他的答案爲更典型的治療,包括轉換到原始指針)上的unique_ptr

+2

OP特意要求一個演員操作符'T *'。 – HighCommander4

+0

事實並非如此,該標準要求對bool進行明確的*轉換,而bool則依賴於對bool的上下文轉換。 –

+0

@HighCommander:嗯,我可以非常明確地回答我的問題。它是問題的標題。不過,@LucDanton有一個更好的觀點。我沒有('有意識地')意識到在某些上下文中的使用實際上會觸發_explicit_轉換爲bool。嗯。學會了今天的東西:) – sehe

2

主要「危險」中提供的隱式轉換運算符(以原始指針)從莖unique_ptr應該爲單一所有權語義建模。這也是爲什麼它不可能複製unique_ptr,但它可以被移動。

考慮這個「危險」的例子:

class A {}; 

/* ... */ 

unique_ptr<A> a(new A); 

A* a2 = a; 
unique_ptr<A> a3(a2); 

現在 unique_ptr S模式在對象單一所有制的語義指向和自由世界的命運 - 不,在宇宙 - 掛在天平上。

好吧,我有點戲劇性,但這就是主意。

就解決方法而言,我通常只需在指針上調用.get()並完成它,小心地認識到我只是got()上缺少所有權。

鑑於您有一個很大的遺留代碼庫,您嘗試使用unique_ptr進行遷移,我認爲您的轉換包裝很好 - 但只是假設您和您的同事不會在未來維護此代碼時。如果這是你可能發現的可能性(我通常會因爲我是偏執狂),我會嘗試改進所有現有的代碼,以顯式調用.get(),而不是提供隱式轉換。編譯器會很高興地找到你需要做出這個改變的所有實例。