C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 陷阱:静态堆栈变量Singleton类大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经有一些使用指针的单例类:

class Logger
{
public:

    static Logger* Instance()
    {
        if (!m_pInstancE) m_pInstance = new Logger;
        return m_pInstance;
    }
private:
    Logger();
    Logger(Logger const&);
    Logger& operator=(Logger const&);
    static Logger* m_pInstance;
};

但是,有一种更简单的方法,使用引用:

class Logger
{
public:
    static Logger& Instance()
    {
        static Logger tHelogger;
        return tHelogger;
    }
private:
    Logger();
    Logger(Logger const&);
    Logger& operator=(Logger const&);
    ~Logger();
};

阅读文章C++ Singleton design pattern,它警告第二种方式:

我无法理解,有人能告诉我一个不好的用法,我应该避免它吗?

解决方法

两种选择确实存在问题.

典型的单身人士

class Logger
{
public:

    static Logger* Instance()
    {
        if (!m_pInstancE) m_pInstance = new Logger;
        return m_pInstance;
    }
private:
    Logger();
    Logger(Logger const&);
    Logger& operator=(Logger const&);
    static Logger* m_pInstance;
};

代码不是线程安全的,因此对新Logger的调用可能会多次发生(在不同的线程中).它还会泄漏Logger实例(因为它永远不会被删除),如果应该执行析构函数,这可能是一个问题.

梅耶的辛格尔顿

class Logger
{
public:
    static Logger& Instance()
    {
        static Logger tHelogger;
        return tHelogger;
    }
private:
    Logger();
    Logger(Logger const&);
    Logger& operator=(Logger const&);
    ~Logger();
};
@H_868_5@meyer’s Singleton的问题确实是由于对象的破坏.从main返回后,所有全局变量的析构函数将按照构造这些全局变量的相反顺序运行1.这就好像这些全局变量是在堆栈上构造的.

如果在Logger之前构造了一个对象,并试图在它自己的析构函数中使用它;然后它将使用已经被破坏的对象,导致未定义的行为.

1更准确地说,它们的构造函数以相反的顺序完成.

最简单的选择是重新审视典型单身人士:

class Logger {
public:
    static Logger& Instance() {
        static Logger* L = new Logger;
        return *L;
    }
private:
    ...
};

这现在是线程安全的,但仍然泄漏.但实际上这里需要泄漏,因为它可以保证这个对象比任何其他析构函数都被调用的时间更长.警告:如果你曾经在析构函数中做过一些事情,它将永远不会运行.

还有其他的变化,例如Alexandrescu的凤凰Singleton从它的灰烬中回来,如果它在它死后需要它;但是,在破坏期间获得线程安全性和安全性很难实现.

大佬总结

以上是大佬教程为你收集整理的c – 陷阱:静态堆栈变量Singleton类全部内容,希望文章能够帮你解决c – 陷阱:静态堆栈变量Singleton类所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。