簡體   English   中英

std :: make_shared里面的原始指針

[英]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中使用原始指針是否會使使用智能指針獲得的任何好處無效? 或者兩種方式都一樣嗎? 謝謝你,我感謝這篇文章的任何答案。

不,這就是智能指針的全部目的。 您不再負責維護原始指針。 智能指針對象是。 智能指針對象獲得原始指針的所有權。 當智能指針過期(超出范圍或被刪除)時,它將自動刪除它擁有的指針。 這里重要的是范圍:這樣你就不必記得在你returnthrow某個地方時自己刪除它。

unique_ptr試圖描述只有一個當前使用該對象的執行線程的概念。 shared_ptr通過聲明可能有多個線程試圖同時訪問它來擴展它。 但請記住: shared_ptr不保證它指向的對象的並發性或安全性。 它只保證指針本身的並發性和安全性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM