我创建了一个父类来处理带有智能指针的单例模式:
.h文件:
template<class singleType>
class Singleton
{
public:
static std::shared_ptr<singleType> GetInstance();
private:
static std::weak_ptr<singleType> m_singleObject;
};
.cpp文件:
template<class singleType>
std::shared_ptr<singleType> Singleton<singleType>::GetInstance()
{
auto shareObject = m_singleObject.Lock();
if (!shareObject)
{
shareObject.reset(new singleType);
m_singleObject = shareObject;
}
return shareObject;
}
不确定这是使用智能指针的正确方法吗? 有什么想法吗?
非常感谢
答案 0 :(得分:4)
我做了一些研究,所以现在我会发一个答案。
代码看起来都应该工作,并且是智能指针的正确用法。唯一的问题是你究竟想要单身人士的行为。这应该像教科书单例EXCEPT一样行为,如果当前没有任何指针指向单例,它将自行删除。这种行为实际上取决于程序的实现。如果你想让singelton只在它使用时存在,那么我会说它去吧。
我会避免经常造成和破坏singelton,特别是如果建筑和解构特别密集。如果它不断被创建和删除,那么你可能会更好地使用更标准的单例实现。标准单例行为往往是单例仅在程序运行期间创建一次,并且永远不会被删除。
我认为这是一个聪明的实现,因为你有使用它,我可能不得不借用这个想法。
答案 1 :(得分:4)
您的代码不是线程安全的。
名称lock
可能表示并发访问被阻止,但实际上没有这样的保证:当多个线程同时调用您的GetInstance
函数时,您将获得多个实例,而不是保证单个实例。< / p>
您需要在GetInstance
函数生命周期的整个持续时间内创建显式锁。请注意,这当然不是很有效。
答案 2 :(得分:3)
已经讨论了此实现的优缺点。但是有一堆错误:
1)由于这是一个模板,你必须将你的实现移动到标题中,否则链接器找不到它。
2)weak_ptr的.lock()
函数不是大写字母。
3)不要忘记实例化
template<class singleType>
std::weak_ptr<singleType> Singleton<singleType>::m_singleObject;
4)更好地使用shareObject = std::make_shared<singleType>(singleType());
代替new
:http://herbsutter.com/gotw/_103/
5)正如Konrad所说:它不是线程安全的。
答案 3 :(得分:1)
据我所知,这应该没问题。您将避免乱序破坏问题,但在创建初始实例后创建新实例可能会出现问题。这个单例在任何时候都只有一个实例存活,但是在程序运行过程中,运行多个实例可能总体上存在。
这种破坏和娱乐在表现方面也可能是不受欢迎的,不仅仅是副作用。