Qt系列文章目录
前言
今天写了一个单例模式,报错如下
ProjectWin.obj👎 error: LNK2001: 无法解析的外部符号 “private: static class ProjectWin * ProjectWin::m_pInstance” (?m_pInstance@ProjectWin@@0PEAV1@EA)
debug\ImageManageSys.exe👎 error: LNK1120: 1 个无法解析的外部命令
一、单例模式是什么?
单例模式就是指一个类在整个程序中只有一个实例。确保一些不需要重复创建的类创建多余的实例。特别是某些工具类,在所有地方使用该类都只需要一个实例。包括线程安全但可能会造成系统资源浪费的饿汉模式,以及懒汉模式和懒汉模式所谓的单例模式,简单的总结有两点:
1.确保一个类只能创建一个实例
2.能够提供一个访问类对象的全局指针
优点:
在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就防止其它对象对自己的实例化,确保所有的对象都访问一个实例
单例模式具有一定的伸缩性,类自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。
提供了对唯一实例的受控访问。
由于在系统内存中只存在一个对象,因此可以节约系统资源,当需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能。
允许可变数目的实例。
避免对共享资源的多重占用。
缺点:就是不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化(在多线程中),单例就会引起数据的错误,不能保存彼此的状态。
二、使用步骤
1.懒汉模式
单例模式有俩种实现方式:
懒汉模式:故名思义,不到万不得已就不会去实例化类,也就是说在第一次用到类实例的时候才会去实例化。
(类加载时不初始化)
饿汉式模式:在单例类定义的时候就进行实例化。
(在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快)
#include <iostream>
using namespace std;
class Singleton
{
private:
Singleton(){};
~Singleton(){};
public:
static Singleton * getInstance();
static void destory()
{
if(_pInstance)
{
delete _pInstance;
}
}
private:
static Singleton * _pInstance;
};
Singleton * Singleton::_pInstance = NULL;
Singleton * Singleton::getInstance()
{
if(NULL == _pInstance)
{
_pInstance = new Singleton;
}
return _pInstance;
}
2.带界面的单例
#ifndef PROJECTWIN_H
#define PROJECTWIN_H
#include <QWidget>
#include <QStandardPaths>
#include <QDir>
#include <QDebug>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QGridLayout>>
#include <QVector>
#include "FileMonitorMgr.h"
namespace Ui {
class ProjectWin;
}
const QString styles = "QTreeView\
{\
background-color: #5B677A;\
font-size:17px;\
color: white;\
}\
QTreeView::item:hover\
{\
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1);\
border: 1px solid #bfcde4;\
}\
QTreeView::item:hover\
{\
background: rgb(69, 187, 217);\
}\
QTreeView::item:selected:active\
{\
background: rgb(255, 62, 150);\
}\
QTreeView::item:selected:!active\
{\
background: rgb(63, 147, 168);\
}\
QTreeView::branch\
{\
background:#5B677A;\
}\
QTreeView::branch:has-children:!has-siblings:closed,QTreeView::branch:closed:has-children:has-siblings\
{\
border-image: none;\
background:#5B677A;\
image: url(image/Folder-1.png);\
}\
QTreeView::branch:open:has-children:!has-siblings,QTreeView::branch:open:has-children:has-siblings\
{\
border-image: none;\
background:#5B677A;\
image: url(image/Open-Folder.png);\
}";
class ProjectWin : public QWidget
{
Q_OBJECT
public:
static ProjectWin* getInstance();
~ProjectWin();
FileMonitorMgr *m_fileMgr;
private:
QTreeWidget* m_picTree;
private:
void initWidget();
void initPicTree();
private:
Ui::ProjectWin *ui;
QGridLayout* m_grid;
QWidget* m_centralWidget;
QTabWidget* m_tabWidget;
static ProjectWin* m_pInstance;
private:
explicit ProjectWin(QWidget *parent = nullptr);
static void destroyInstance();
public:
Q_SIGNALS:
void sigShowImageBorder(const QString &imageName);
public Q_SLOTS:
void slotPicTree(QVector<QString> lst, QString path);
void onItemClicked(QTreeWidgetItem *item, int column);
};
#endif // PROJECTWIN_H
#include "ProjectWin.h"
#include "ui_ProjectWin.h"
#pragma execution_character_set("utf-8")
ProjectWin* ProjectWin::m_pInstance = nullptr;
ProjectWin* ProjectWin::getInstance()
{
if(!m_pInstance)
{
m_pInstance = new ProjectWin();
atexit(destroyInstance);
}
return m_pInstance;
}
void ProjectWin::destroyInstance()
{
if(m_pInstance)
{
delete m_pInstance;
m_pInstance = nullptr;
}
}
ProjectWin::~ProjectWin()
{
delete ui;
}
ProjectWin::ProjectWin(QWidget *parent) :
QWidget(parent),
ui(new Ui::ProjectWin)
{
ui->setupUi(this);
m_tabWidget = ui->tabWidget; // 初始化 QTabWidget 指针
m_picTree = new QTreeWidget();
//打开右键菜单属性
m_picTree->setContextMenuPolicy(Qt::CustomContextMenu);
m_picTree->setColumnCount(1);//设置有1列
// m_picTree->setHeaderLabels(QStringList() << u8"彩C" );
m_picTree->setHeaderHidden(true);
connect(m_picTree, &QTreeWidget::itemClicked, this, &ProjectWin::onItemClicked);
}
void ProjectWin::onItemClicked(QTreeWidgetItem *item, int column)
{
QString imageName = item->text(0);
emit sigShowImageBorder(imageName);
}
void ProjectWin::initWidget()
{
// m_picTree->header()->hide();//设置隐藏头
}
void ProjectWin::initPicTree()
{
}
void ProjectWin::slotPicTree(QVector<QString> lst, QString path)
{
QTreeWidgetItem* topItem = new QTreeWidgetItem(m_picTree);
topItem->setText(0, path);
topItem->setCheckState(0, Qt::Checked);
m_picTree->addTopLevelItem(topItem);
int count = lst.size();
//添加顶层节点
if (lst.size() > 0)
{
for (int i = 0; i < lst.size(); i++)
{
//int size = lst.at(i).size();
//int pos = lst.at(i).lastIndexOf("/");
//QString temp = lst.at(i).right(size - pos - 1);
QTreeWidgetItem* item = new QTreeWidgetItem(topItem);
item->setText(0, lst.at(i));
item->setCheckState(0, Qt::Checked);
}
}
m_picTree->expandAll();
// m_grid = new QGridLayout(this);
// m_grid->addWidget(m_picTree);
m_picTree->setStyleSheet(styles);
// this->setLayout(m_grid);
m_tabWidget->addTab(m_picTree, u8"彩C");
}
注意这里一定要初始化静态指针:ProjectWin* ProjectWin::m_pInstance = nullptr;
否则就会报错:
ProjectWin.obj👎 error: LNK2001: 无法解析的外部符号 “private: static class ProjectWin * ProjectWin::m_pInstance” (?m_pInstance@ProjectWin@@0PEAV1@EA)
debug\ImageManageSys.exe👎 error: LNK1120: 1 个无法解析的外部命令
2.饿汉模式
#ifndef SINGLETONONE
#define SINGLETONONE
class Singleton
{
public:
static Singleton* getInstance()
{
return instance;
}
public:
~Singleton(){}
private:
Singleton() = default;
Singleton(Singleton const&) = delete;
Singleton& operator=(Singleton const&) = delete;
Singleton(Singleton const&&) = delete;
Singleton& operator=(Singleton const&&) = delete;
private:
static Singleton *instance;
};
Singleton* Singleton::instance = new Singleton;
#endif // SINGLETONONE
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。