std::make_shared 内的原始指针

Raw pointer inside std::make_shared

我欣然承认仍在学习 C/C++ 中指针的更精细注释以及它们的工作原理,但在做了一些研究之后,我只是不 感觉 熟悉下面的代码。

std::shared_ptr<CDKSCREEN> cdkScreen;
cdkScreen = std::make_shared<CDKSCREEN>(*initCDKScreen(newWin.get()));

std::shared_ptr 中使用原始指针是否会抵消您从使用智能指针中获得的任何好处?还是两种方式都一样?谢谢你,我很感激对此 post.

的任何回答

编辑: 我没有意识到 reset() 函数的全部用途,但感谢所有向我指出这一点的人。看来我也可以将自定义析构函数传递给 std::shared_ptr,如下所示:

std::shared_ptr<CDKSCREEN> cdkScreen(initCDKScreen(newWin.get()), destroyCDKScreen);

Does the usage of raw pointers inside a std::shared_ptr nullify any of the benefits you get from using smart pointers? Or is it just all the same either way? Thank you and I appreciate any answers to this post.

不,这就是智能指针的全部目的。您不再负责维护原始指针。智能指针对象是。智能指针对象拥有原始指针的所有权。当智能指针过期(超出范围,或被删除)时,它会自动删除它拥有的指针。这里重要的一点是范围:这样你就不必记得在某处 returnthrow 时自己删除它。

unique_ptr 试图描述只有一个当前执行线程正在使用该对象的概念。 shared_ptr 对此进行了扩展,指出 可能 有多个线程试图同时访问它。 但请记住:shared_ptr 不保证它指向的对象的并发性或安全性。它只保证指针本身的并发性和安全性。

我相信您的示例实际上存在内存泄漏。让我们分解一下:

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 returns 必须是 deleted 的东西,那么在这种情况下我会避免 copy/move ctor 而只是 .reset() 指向它的智能指针:

std::shared_ptr<CDKSCREEN> cdkScreen;
cdkScreen.reset(initCDKScreen(newWin.get()));

实际上,因为它甚至有一个构造函数重载,所以继续

std::shared_ptr<CDKSCREEN> cdkScreen { initCDKScreen(newWin.get()) };

如果需要自定义销毁工具,您可以将其作为第二个参数传递给指针。它非常有意义,智能指针 类 就是为此而设计的。

我想你想保存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);