[英]Raw pointer inside std::make_shared
comfortable with the code below. 我很樂意繼續學習C / C ++中指針的精細筆記以及它們是如何工作的,但經過一些研究后,我對下面的代碼不舒服。
std::shared_ptr<CDKSCREEN> cdkScreen;
cdkScreen = std::make_shared<CDKSCREEN>(*initCDKScreen(newWin.get()));
在std::shared_ptr
使用原始指針是否會使使用智能指針獲得的任何好處無效? 或者兩種方式都一樣嗎? 謝謝你,我感謝這篇文章的任何答案。
編輯:我沒有意識到reset()
函數的全部目的,但感謝所有向我指出這一點的人。 看來我也可以將自定義析構函數傳遞給std::shared_ptr
,如下所示:
std::shared_ptr<CDKSCREEN> cdkScreen(initCDKScreen(newWin.get()), destroyCDKScreen);
我想你想保存initCDKScreen返回的指針。 在這種情況下,您不必使用make_shared
。 您應該將指針傳遞給構造函數或shared_ptr::reset(...)
:
std::shared_ptr<CDKSCREEN> cdkScreen(initCDKScreen(newWin.get()));
由於CDKSCREEN
應該被destroyCDKScreen(CDKSCREEN *screen)
破壞而不是delete
,你應該寫這樣的東西:
std::shared_ptr<CDKSCREEN> cdkScreen(initCDKScreen(newWin.get()), destroyCDKScreen);
要么
std::shared_ptr<CDKSCREEN> cdkScreen;
cdkScreen.reset(initCDKScreen(newWin.get()), destroyCDKScreen);
我相信你的例子實際上有內存泄漏。 讓我們分解一下:
CDKSCREEN* screen = initCDKScreen(newWin.get());
CDKSCREEN& screenRef = *screen;
// auto screenSharedPtr = std::make_shared<CDKSCREEN>(screenRef);
// this is basically:
CDKSCREEN* screen2 = new CDKSCREEN(screenRef);
shared_ptr<CDKSCREEN> screenSharedPtr (screen2);
如您所見,正在制作副本,但不會刪除原始指針。 哎呀。
如果initCDKScreen
返回的東西必須只是delete
d,那么在這種情況下我會避免復制/移動ctor,只是.reset()
指向它的智能指針:
std::shared_ptr<CDKSCREEN> cdkScreen;
cdkScreen.reset(initCDKScreen(newWin.get()));
實際上,因為它甚至有一個構造函數重載,所以繼續
std::shared_ptr<CDKSCREEN> cdkScreen { initCDKScreen(newWin.get()) };
如果需要自定義銷毀工具,則可以將其作為第二個參數傳遞給指針。 它非常有意義,智能指針類就是為此而設計的。
在std :: shared_ptr中使用原始指針是否會使使用智能指針獲得的任何好處無效? 或者兩種方式都一樣嗎? 謝謝你,我感謝這篇文章的任何答案。
不,這就是智能指針的全部目的。 您不再負責維護原始指針。 智能指針對象是。 智能指針對象獲得原始指針的所有權。 當智能指針過期(超出范圍或被刪除)時,它將自動刪除它擁有的指針。 這里重要的是范圍:這樣你就不必記得在你return
或throw
某個地方時自己刪除它。
unique_ptr
試圖描述只有一個當前使用該對象的執行線程的概念。 shared_ptr
通過聲明可能有多個線程試圖同時訪問它來擴展它。 但請記住: shared_ptr
不保證它指向的對象的並發性或安全性。 它只保證指針本身的並發性和安全性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.