std :: make_shared里面的原始指针

时间:2015-10-08 16:30:34

标签: c++ pointers c++11 raii

我很乐意继续学习C / C ++中指针的精细笔记以及它们是如何工作的,但经过一些研究后,我感觉对以下代码感到满意。< / p>

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);

3 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:4)

我相信你的例子实际上有内存泄漏。让我们分解一下:

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()指向它的智能指针:< / p>

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

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

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

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

答案 2 :(得分:1)

  

在std :: shared_ptr中使用原始指针是否会使使用智能指针带来的任何好处无效?或者两种方式都一样吗?谢谢你,我感谢你对这篇文章的任何答案。

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

unique_ptr试图描述仅使用该对象的当前执行线程的概念。 shared_ptr通过声明可能是多个尝试同时访问它的线程来扩展它。 但请记住:shared_ptr不保证它所指向的对象的并发性或安全性。它只保证指针本身的并发性和安全性。