Skip to content

Commit

Permalink
Use std::unique_ptr internally in Utility
Browse files Browse the repository at this point in the history
The call to `std::make_unique<Type>` is perhaps a little weird since we immediately `release` the value right after. The main reason for using `std::make_unique` here is to avoid a naked `new`. The use of the `unique_ptr` here is a bit inconvenient, since we need to return the value of that type, but any transfer of ownership will clear out the original `unique_ptr`, and the target of the transfer is for a possibly different base type `T`, which can't be returned directly as type `Type`. We either need a `static_cast`, or do a bit of pointer shuffling using `release`.
  • Loading branch information
DanRStevens committed Dec 18, 2024
1 parent f326867 commit 4f21759
Showing 1 changed file with 10 additions and 11 deletions.
21 changes: 10 additions & 11 deletions NAS2D/Utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// ==================================================================================
#pragma once

#include <memory>
#include <utility>
#include <type_traits>
#include <stdexcept>
Expand Down Expand Up @@ -71,7 +72,7 @@ namespace NAS2D
{
if (!mInstance)
{
mInstance = new T();
mInstance = std::make_unique<T>();
}

return *mInstance;
Expand Down Expand Up @@ -132,12 +133,11 @@ namespace NAS2D
static Type& init(Args&&... args)
{
// Instantiate a new object with forwarded constructor arguments
auto newInstance = new Type(std::forward<Args>(args)...);

delete mInstance;

mInstance = newInstance;
return *newInstance;
auto newInstance = std::make_unique<Type>(std::forward<Args>(args)...);
// The new instance may be a sub-type of T, so return as sub-type
auto typedNewInstance = newInstance.release();
mInstance.reset(typedNewInstance);
return *typedNewInstance;
}


Expand All @@ -149,15 +149,14 @@ namespace NAS2D
*/
static void clear()
{
delete mInstance;
mInstance = nullptr;
mInstance.reset();
}

private:
static T* mInstance;
static std::unique_ptr<T> mInstance;
};


template <typename T>
T* Utility<T>::mInstance = nullptr;
std::unique_ptr<T> Utility<T>::mInstance{};
} // namespace

0 comments on commit 4f21759

Please sign in to comment.