A colleague at work was recently tasked with refactoring some legacy code and came across the good old
std::auto_ptr. In C++0x it has been deprecated (and later removed outright; I can’t even compile
std::auto_ptrcode in Visual Studio 2017 nor Xcode 10.1) so it was his job to rewrite it in the modern C++ way. The code that my colleague came across had another problem. Can you spot it?
std::auto_ptrp1(new T[3]);
std::auto_ptrwas never meant to hold pointers to arrays. So the code above, assuming it didn’t crash, was leaking memory (regardless of what it holds,
std::auto_ptralways calls
deletein its destructor;
delete[]was needed in the code above).
So how do we refactor legacy
std::auto_ptrcode into modern C++? The answer is
std::unique_ptr(https://en.cppreference.com/w/cpp/memory/unique_ptr). A
std::auto_ptrholding a pointer to a single object of type
T, in modern C++, becomes:
auto p2 = std::make_unique();
std::make_uniquecan forward constructor parameters to
T::T, like this:
auto p3 = std::make_unique("string parameter");
And an array of
T‘s of size
Nbecomes:
auto p4 = std::make_unique(N);
Note that for
std::make_uniqueto be able to create an array of
T‘s,
Tmust have a
T::T()(default constructor; or a constructor with all parameters having default values:
T::T(int x = 0)).
Should we use container or std::array for dynamic array ? I think it’s better than warping pointer to an array with smart pointer . 🙂