[英]Is returning a raw pointer instead of unique_ptr good coding practice?
[英]Is Singleton with static unique_ptr a good practice
我在一個項目中工作,其中 Singletons 通常是這樣實現的:
class Singleton
{
public:
static Singleton& get();
virtual ~Singleton() = default;
// Used for unit tests
static void reset();
protected:
static std::unique_ptr<Singleton>& instance();
};
unique_ptr<Singleton>& Singleton::instance()
{
static unique_ptr<Singleton> instance;
return instance;
}
Singleton& Singleton::get()
{
auto& instance = instance();
if (!instance) {
// We cannot use make_unique<T>() as constructor is private
instance = unique_ptr<Singleton>(new Singleton());
}
return *instance;
}
void Singleton::reset() { instance().reset(); }
// Private constructor
Singleton::Singleton() {}
這里不需要線程安全。
使用static unique_ptr
有什么好處嗎?
使用unique_ptr<T>(new T())
創建 Singleton 的后果是什么?
由於我們的單例可以攜帶(一些)全局 state,為了測試目的實現了一個 public reset() ,這是唯一的方法嗎?可以改進嗎?
我在這里找到了 C++ singleton 設計模式的一些示例。 但從來沒有像我一樣用 unique_ptr 實現過。
有兩種方法可以重置 Meyer 的 singleton:
#include <new>
class Singleton
{
public:
static Singleton& instance() {
static Singleton instance;
return instance;
}
virtual ~Singleton() = default;
// Option 1 - easy and convinient if Singleton is copyable or movable
void reset1() {
*this = {};
}
// Option 2 - works always
void reset2() {
this->~Singleton();
new (this) Singleton;
}
private:
Singleton() {}
};
第二個選項基本上就是做你正在做的釋放/創建std::unique_ptr
,除了沒有釋放/分配存儲。
無需使用 std::unique_ptr。 使用參考資料
class Singleton
{
public:
static Singleton& instance();
virtual ~Singleton() = default;
// Used for unit tests
void reset();
private:
Singleton();
int stuff;
};
Singleton& Singleton::instance()
{
static Singleton instance;
return instance;
}
void Singleton::reset() { stuff = 0; }
// Private constructor
Singleton::Singleton() {}
請注意,此設計主要由您對reset
function 的要求決定。這會阻止您使用某些 Singleton 實現,例如Meyer 的 Singleton 。
通常,您希望 singleton 實現不允許執行reset
方法,因為現在您的 singleton 不再是真正的 singleton。 但出於測試目的,“淡化” singleton 當然可能是有意義的。
如果多線程安全不是問題,那么您的 singleton 實現過於復雜,可以簡化為:
class Singleton
{
public:
static Singleton& get() {
if (!mInstance) {
mInstance = std::unique_ptr<Singleton>(new Singleton());
}
return *mInstance;
}
static void reset() { mInstance.reset(); }
private:
static inline std::unique_ptr<Singleton> mInstance{};
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.