在我的案例中,我是否需要销毁单例实例?
Do I need to destroy singleton instance in my case?
如果在我使用如下单例实例后进程终止。
是否存在内存泄漏?
- 如果是,我该如何解决这个问题?
- 是否需要添加"destroyInstance"成员函数?
- 如果是,当多线程已经引用单例实例时,
如何确保多线程安全?
(我需要添加引用计数吗?)
我想知道如果我需要考虑所有这些,单例模式似乎很复杂。
#include <mutex>
class Singleton
{
static Singleton *singletonInstance;
Singleton() {}
static std::mutex m_;
public:
static Singleton* getSingletonInstance()
{
std::lock_guard<std::mutex> lock(m_);
if(singletonInstance == nullptr)
{
singletonInstance = new Singleton();
}
return singletonInstance;
}
}
您不需要为单例手动管理内存。这是 std::unique_ptr
:
的示例
#include <memory>
#include <mutex>
class Singleton
{
static std::unique_ptr<Singleton> singletonInstance;
Singleton() {}
static std::mutex m_;
public:
static Singleton* getSingletonInstance()
{
std::lock_guard<std::mutex> lock(m_);
if (!singletonInstance)
{
singletonInstance = std::make_unique<Singleton>();
}
return singletonInstance.get();
}
};
进程正常结束时会调用std::unique_ptr
析构函数。另外,不需要同步析构函数。
但更好的是,你应该使用 Scott Meyer 的单例:
class Singleton {
public:
static Singleton& getSingletonInstance() {
static Singleton instance;
return &instance;
}
};
上面的例子是线程安全的,即使没有使用明确的锁。
对于您 Q3,即使成员函数 getSingletonInstance
可能是线程安全的,单例的使用可能不是。共享可变状态本质上是线程不安全的。
如果在我使用如下单例实例后进程终止。 是否存在内存泄漏?
- 如果是,我该如何解决这个问题?
- 是否需要添加"destroyInstance"成员函数?
- 如果是,当多线程已经引用单例实例时, 如何确保多线程安全? (我需要添加引用计数吗?)
我想知道如果我需要考虑所有这些,单例模式似乎很复杂。
#include <mutex>
class Singleton
{
static Singleton *singletonInstance;
Singleton() {}
static std::mutex m_;
public:
static Singleton* getSingletonInstance()
{
std::lock_guard<std::mutex> lock(m_);
if(singletonInstance == nullptr)
{
singletonInstance = new Singleton();
}
return singletonInstance;
}
}
您不需要为单例手动管理内存。这是 std::unique_ptr
:
#include <memory>
#include <mutex>
class Singleton
{
static std::unique_ptr<Singleton> singletonInstance;
Singleton() {}
static std::mutex m_;
public:
static Singleton* getSingletonInstance()
{
std::lock_guard<std::mutex> lock(m_);
if (!singletonInstance)
{
singletonInstance = std::make_unique<Singleton>();
}
return singletonInstance.get();
}
};
进程正常结束时会调用std::unique_ptr
析构函数。另外,不需要同步析构函数。
但更好的是,你应该使用 Scott Meyer 的单例:
class Singleton {
public:
static Singleton& getSingletonInstance() {
static Singleton instance;
return &instance;
}
};
上面的例子是线程安全的,即使没有使用明确的锁。
对于您 Q3,即使成员函数 getSingletonInstance
可能是线程安全的,单例的使用可能不是。共享可变状态本质上是线程不安全的。