13

我创建了一个父类来使用智能指针处理单例模式:

.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;
}

不确定这是使用智能指针的正确方法吗?任何想法?

非常感谢

4

4 回答 4

4

已经讨论了这种实现的优缺点。但是有一堆bug:

1)由于这是一个模板,您必须将您的实现移动到标题中,否则链接器找不到它。

2).lock()weak_ptr 的功能不是大写的。

3)不要忘记实例化

template<class singleType> 
std::weak_ptr<singleType> Singleton<singleType>::m_singleObject;

4)更好地使用shareObject = std::make_shared<singleType>(singleType());而不是newhttp ://herbsutter.com/gotw/_103/

5)正如康拉德所说:它不是线程安全的。

于 2013-04-22T08:05:55.457 回答
4

我做了一些研究,所以现在我会发布一个答案。

代码看起来应该可以工作,并且是智能指针的正确用法。唯一的问题是您希望单例的行为究竟如何。这应该表现得像一个教科书单例,除了如果当前没有任何东西有指向单例的指针,它将删除自己。这种行为实际上取决于您的程序的实现。如果您希望单只在使用时才存在,那么我会说去吧。

我会避免过于频繁地创建和销毁单点,尤其是在构建和解构特别密集的情况下。如果它不断被创建和删除,那么使用更标准的单例实现可能会更好。标准的单例行为往往是单例在程序运行期间只创建一次,并且永远不会被删除。

我认为这是一个聪明的实现,因为你有它的用途,我可能不得不借用这个想法。

于 2013-04-22T06:06:08.177 回答
4

您的代码不是线程安全的。

名称lock可能暗示并发访问被阻止,但实际上并没有这样的保证:当多个线程同时调用您的GetInstance函数时,您将获得多个实例而不是保证单个实例。

您需要在函数的整个GetInstance生命周期内创建一个显式锁。请注意,这当然不是很有效。

于 2013-04-22T07:45:25.260 回答
1

据我所知,这应该没问题。您将避免乱序破坏问题,但在创建初始实例后创建新实例可能会出现问题。这个单例在任何时候都只有一个实例处于活动状态,但在程序运行的过程中,可能有多个实例整体处于活动状态。

这种破坏和娱乐在性能方面也可能是不受欢迎的,不仅在副作用方面。

于 2013-04-22T06:05:51.933 回答