2017-10-10 62 views
5

方案原始指針:
我使用從它返回原始指針到SomeClass舊C++庫其中SomeClass是從庫頭一個導出類中的方法說SomeClass.h存儲從方法返回到智能指針

下面是我使用的LibraryMethod簽名:

SomeClass* LibraryMethod(); 

我用不上更改庫。我只使用二進制&公共頭,這是一個典型的場景。

我不想在我的部分代碼中使用原始指針。因此,我在使用庫API的代碼中有shared pointerSomeClass

std::shared_ptr<SomeClass> some_class; 

我初始化這樣避免了原始指針存儲到SomeClass

some_class = (std::shared_ptr<SomeClass>)LibraryMethod(); 

這基本上工作,但我想在這裏瞭解詳細信息

問:
是的高於正確的技術?
我在這裏造成泄漏嗎?
有沒有更好的技術來處理這種情況?

+3

您不應該混用不同版本的編譯器編譯的C++代碼。這樣做會導致很難發現異常情況。 – rustyx

+3

你確定你需要'shared_ptr <>'而不是'unique_ptr <>'嗎? – gurka

+0

@RustyX如果您有權訪問更改庫的內部代碼,您的觀點將是有效的。但不幸的是不是 –

回答

6

你應該真正把它作爲

auto some_class = std::shared_ptr<SomeClass>(LibraryMethod()); 

這假定LibraryMethod被分配的指針,並給予內存的所有權轉讓給你。

上述代碼,您要使用C風格的類型轉換(這可能會導致一個reinterpret_cast)原始指針轉換爲std::shared_ptr。相反,你想要使用返回的原始指針construct a std::shared_ptr

+0

我看到你在這裏使用花括號的方式有明顯的不同。我曾在'std :: shared_ptr '周圍使用過它,但是您已經在'LibraryMethod()'方法調用周圍使用了它。這看起來是一種更好的方式,可以給予指針的所有權。 –

+1

它不只是*看起來不同,這兩個版本實際*是*不同。你的方法正在做一個C風格的演員,可能無法正常工作。該方法正在使用原始指針作爲參數構建一個'std :: shared_ptr'。 – CoryKramer

+0

「*構建共享指針*」。這比在下面的答案中建議的重置更好嗎?這裏真的很好的建議。想要比較它們以理解最佳方法 –

3

該代碼有效,但它很醜,很脆弱。爲什麼要將不錯的現代C++(智能指針)與C風格的古老而危險的東西混合在一起?你好得多關閉主叫reset

some_class.reset(LibraryMethod()); 

上述假設(如你的問題似乎表明),你已經std::shared_ptr<SomeClass> some_class;某處聲明,要重新分配它。如果你只是LibraryMethod調用之前創建some_class,這是更好的,直接初始化它:

std::shared_ptr<SomeClass> some_class(LibraryMethod()); 

這則相當於CoryKramer's answer


注意,但是,有一個重要的假設隱藏在這一切的代碼:即LibraryMethod返回通過new和它的調用者負責,最終通過調用delete釋放內存動態分配指向內存的指針。

+0

對你來說,如果我們擁有指針的所有權,那麼我們隱含地做着調用delete所需的儀式? –

+2

@Programist當std :: shared_ptr最後一個超出範圍時,通常會這樣做,除非你提供了一個刪除器來執行其他操作。 – Angew

3

在你的情況下,正確的方法應該是使用shared_ptr的構造:

std::shared_ptr<SomeClass> sPtr(LibraryMethod()); 

首先你應該知道什麼由LibraryMethod()返回的指針的真正含義,大多數圖書館返回原始指針只是說「嘿,你可以通過這個指針訪問這個對象,但要注意,我仍然是負責管理它的人,所以...不要刪除它!」

如果您確定在調用之後你負責管理它,然後確定,你可以使用一個shared_ptr和平的心神。

2

上述是否正確的技術?

是的,由於LibraryMethod分配資源與new,並且庫用戶負責刪除它。用智能指針包裝原始指針被廣泛用於舊式庫。

我在這裏引起泄漏嗎?

不,如果你做得對。我同意其他的答案,但你也可以這樣做:

std::shared_ptr<SomeClass> some_class(LibraryMethod()); 

是否有更好的方法來處理這樣的情況?

要仔細考慮的一件事是由LibraryMethod分配的資源的所有權。有人認爲,shared_ptr是邪惡的,因爲它只是一個更好的方式來引入一個難以跟蹤的依賴的全局。例如,參見Sean Parent的this talkthis one @8:40。如果您的代碼中存在消耗並擁有該資源的實體,則可以考慮使用std::unique_ptr

此外,如果LibraryMethod可能會拋出異常,您必須相應地處理這種情況。