I readily admit to still learning the finer notes of pointers in C/C++ and how they work but after doing some research, I just don't feel comfortable with the code below.
std::shared_ptr<CDKSCREEN> cdkScreen;
cdkScreen = std::make_shared<CDKSCREEN>(*initCDKScreen(newWin.get()));
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.
EDIT:
I did not realize the full purpose of the reset()
function but thank you to all who pointed this out to me. It seems I can also pass a custom destructor to std::shared_ptr
as well, like below:
std::shared_ptr<CDKSCREEN> cdkScreen(initCDKScreen(newWin.get()), destroyCDKScreen);
I believe your example actually has a memory leak. Let's break it down:
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);
As you can see, a copy is being made, but the original pointer isn't deleted. Oops.
If initCDKScreen
returns something that has to just be delete
d, then in this case I'd avoid the copy/move ctor and just .reset()
the smart pointer to it:
std::shared_ptr<CDKSCREEN> cdkScreen;
cdkScreen.reset(initCDKScreen(newWin.get()));
Actually, since it even has a constructor overload for that, go ahead and
std::shared_ptr<CDKSCREEN> cdkScreen { initCDKScreen(newWin.get()) };
If a custom destruction facility is needed, you can pass it as a 2nd parameter to the pointer. It makes perfect sense and smart pointer classes were designed for that.