单例模式语法错误静态字段未命名 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;
}
别生我的气。我是 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;
}