我很乐意继续学习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);
答案 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中使用原始指针是否会使使用智能指针带来的任何好处无效?或者两种方式都一样吗?谢谢你,我感谢你对这篇文章的任何答案。
不,这就是智能指针的全部目的。您不再负责维护原始指针。智能指针对象是。智能指针对象获得原始指针的所有权。当智能指针过期(超出范围或被删除)时,它将自动删除它拥有的指针。这里的重点是范围:这样,如果您return
或throw
某处,您不必自己删除它。
unique_ptr
试图描述仅使用该对象的当前执行线程的概念。 shared_ptr
通过声明可能是多个尝试同时访问它的线程来扩展它。 但请记住:shared_ptr
不保证它所指向的对象的并发性或安全性。它只保证指针本身的并发性和安全性。