C++ Smart Pointers
It’s been awhile since my last blog post. It’s also been awhile since I last programmed C++. But recently I’m doing again C++ intensive. I also bought a book about C++. My long-term plan is to re-write all tools in C++. But only the most used onces.
I like how fast native code and how stable the C++ language is. It feels good. We also got new language standards since my last use of C++. C++11, C++14 and C++17. Upcoming C++ standards every 3 years. This motivates my to re-write my tools using C++.
I currently re-writing the Wallet project using C++. Back then I created this project to learn Ruby. The Ruby project will remain. The C++ Wallet project will be a separate Git repository.
I want to use best practice and the latest standard C++17. Therefore I learned that raw pointers are no longer welcome. This is fine. Get rid of raw pointers seems like a good idea. You can do everything like the same way using smart pointers.
Some old APIs need Raw Pointers. In the following example the
f() function is legacy.
class Widget; void f(const Widget*);
So the legacy call would look like this:
const Widget* wp = new Widget(); f(wp); delete wp;
With smart pointers this is now:
#include <memory> // for std::unique_ptr // and std::make_unique() auto wp = std::make_unique<Widget>(); f(w.get()); // no 'delete' needed here anymore
Especially when you do not use
wp after the
f() call the C++11 code can also look like:
#include <memory> // same as above auto wp = std::make_unique<Widget>(); // same f(wp.release());
This will release the ownership of the managed object. But it could lead to a memory leak since
release() will not call the destructor of Widget. Therefore would I recommend not using
release() in this case.
The use case of
release() is useful when you have legacy code like this:
The new created Widget object is not managed on the caller level. So
f() should be responsible to free the Widget. The corresponding C++11 code is the same as above.
#include <memory> auto wp = std::make_unique<Widget>(); f(wp.release());