单例模式语法错误静态字段未命名 non-static 数据成员或基 class

Singleton Pattern Syntax Error static field does not name a non-static data member or base class

别生我的气。我是 c++ 和 qt 的新手 我按照 Gof 的示例使用了单例 calss 但是得到错误

svgview.cpp:11:16: error: member initializer 'm_instance' does not name a non-static data member or base class

我的header

#ifndef SVGVIEW_H
#define SVGVIEW_H
#include <QGraphicsView>

QT_BEGIN_NAMESPACE
class QGraphicsSvgItem;
class QSvgRenderer;
QT_END_NAMESPACE

class SvgView : public QGraphicsView
{
    Q_OBJECT

public:
    static SvgView* Instance();
    void openFile(const QString &fileName);
    QSvgRenderer *renderer() const;

private:
    static SvgView* m_instance;
    QGraphicsSvgItem *m_svgItem;
    SvgView();

};
#endif // SVGVIEW_H

cpp代码:

SvgView::SvgView()
    : QGraphicsView()
    , m_svgItem(nullptr)
    , SvgView::m_instance(nullptr)
{
    setScene(new QGraphicsScene(this));
}

QT 5.14.1 minGW 我做错了什么?

您的解决方案是:

SvgView* SvgView::m_instance = 0;
SvgView::SvgView()
    : QGraphicsView()
    , m_svgItem(nullptr)
{
    setScene(new QGraphicsScene(this));
}
SvgView* SvgView::instance(){
    if (m_instance==0)
    {
        m_instance=new SvgView();
    }
    return m_instance;
}

这个模式引入几个潜在的长期问题的具体设计选择:

1.Inability 使用抽象或接口 类;

2.Difficulty创建子类;

3.High跨应用耦合(易包含难于修改或删除);

4.Difficult 进行测试(单元测试中不能 fake/mock);

5.Difficult 在可变状态的情况下并行化(需要大量锁定);

例如,第一个线程可以从第二行开始获取条件,并在构造函数执行期间被中断。 当第一个线程休眠时,第二个线程启动,它使用相同的代码工作,但是由于第一个线程没有初始化 m_instance,第二个线程也调用 SimpleClass 构造函数和 returns 一个指针到创建的对象。

之后,可以激活第一个线程,再次结束其对象实例的创建并初始化m_instance。 要解决竞争问题,可以使用互斥量(提供的示例使用Qt库,但同步功能目前包含在标准库中)。

简单的解决方案是使用互斥量:

#include <QMutex>
SvgView* SvgView::instance(){
    static QMutex mutex;
    if (m_instance==0)
    {
        mutex.lock();
        if(m_instance==0)
            m_instance=new SvgView();
        mutex.unlock();
    }
    return m_instance;
}