这个Singleton实现有什么问题?

Ida*_*rye 5 c++ singleton

这个想法是在程序结束时删除C++中的Singleton.我们在课堂上学到了这种实现方法:

class Singleton
{

private:
    static Singleton* the_singleton;

protected:
    Singleton()
    {
        static Keeper keeper(this);
        /*CONSTRUCTION CODE*/
    }
    virtual ~Singleton()
    {
        /*DESTRUCTION CODE*/
    }

public:
    class Keeper
    {

    private:
        Singleton* m_logger;

    public:
        Keeper(Singleton* logger):m_logger(logger){}

        ~Keeper()
        {
            delete m_logger;
        }
    };
    friend class Singleton::Keeper;

    static Singleton* GetInstance();
    {
        if (!the_singleton)
            the_singleton = new Singleton();
        return the_singleton;
    }
};

Singleton* Singleton::the_singleton = NULL;
Run Code Online (Sandbox Code Playgroud)

我们的想法是,在第一次创建Singleton时,将在Singleton的C'tor中创建一个静态Keeper对象,一旦程序结束,Keeper将被销毁,反过来将破坏它指向的Singleton实例至.

现在,这个方法对我来说似乎相当麻烦,所以我建议抛弃守护者类并使Singleton的实例成为getInstance方法的静态对象:

<!-- language: c++ -->

class Singleton
{

protected:
    Singleton()
    {
        /*CONSTRUCTION CODE*/
    }

    ~Singleton()
    {
        /*DESTRUCTION CODE*/
    }

public:
    static Singleton &getInstance()
    {
        static Singleton instance;
        return instance;
    }

    /*OBJECT FUNCTIONALITY*/
};
Run Code Online (Sandbox Code Playgroud)

这样,Singleton是在第一次调用getInstance方法时构造的,并在程序结束后销毁.不需要那个守门员课程.

我测试了它并且工作得很好 - 在正确的地方创建并销毁了Singleton.但是,我的TA说这种模式是错误的,尽管他不记得究竟是什么问题.所以我希望以前有人遇到过这个实现,并告诉我它有什么问题.

Ben*_*igt 9

这是错的,但你的修改没有引入问题 - 他们一直都在那里.

现在没有执行单身人士财产.构造函数需要是私有的,而不是受保护的,以确保不创建其他实例.


除此之外,原始代码在多线程场景中完全无法使用. 你的工作将从C++ 0x开始.


如果TA的keeper对象已将全局指针重置为NULL,则他的实现将能够(在单线程环境中)在程序清理期间根据需要重新创建单例.在C++中读取单例模式.但这仍然是单例的一个新实例,这几乎与在调用析构函数后使用单例一样出乎意料.

但是,他忽略了这一点,因此在守门员删除单身人士之后,他会很乐意在程序关闭期间使用无效指针.在你的内容中,即使对象的生命周期已经结束,至少内存区域仍然有效.


您当然会被标记为使用改进版本,这只是表明该类的目的不是教你C++,而是TA对C++的误解.


Ern*_*ill 6

完全没有问题.对于这个应用程序,"守护者"的东西是坚果,恕我直言.

在某些情况下可能需要保证.例如,如果Singleton必须采用构造函数参数,则静态分配它可能是不可能的.或者,如果其构造函数可能失败,则更简单的方法将不允许您恢复或重试.所以在某些情况下,可能需要做一些更复杂的事情.但在许多情况下,这是不必要的.