单例的定义
官方定义:单例是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点。
单例的写法
抓住3点:
- 构造函数私有化(确保只有一个实例)
- 提供一个可以获取构造实例的接口(提供唯一的实例)
- 正常写你需要实现的函数
举个例子
①就是构造函数私有化,把构造函数放在private里
②就是提供一个可以获取实例的接口,这个实例就是私有变量_singleton
③就是正常需要实现的函数,正常咋写就咋写,但最好是独立的且需要多次被使用的
用法
在需要使用单例的文件中添加单例的头文件
举个例子,我要在BlockFileTreeView中使用单例中的函数,那么我就在BlockFileTreeView.cpp中添加单例头文件
#include "ResourceTreeViewSingleton.h"
然后再需要调用函数的地方通过单例的init获取实例,然后调用需要使用的函数
filePath = _fileLocalPath + ResourceTreeViewSingleton::init()->getRelativePath(_currentProcessItem,"");
重点就是这句ResourceTreeViewSingleton::init()->getRelativePath(_currentProcessItem,"");
红色部分是获取单例的实例,黄色部分就是调用单例的函数。
单例代码
.h
#ifndef RESOURCETREEVIEWSINGLETON_H
#define RESOURCETREEVIEWSINGLETON_H
#include <QSharedPointer>
#include <QMutex>
#include <QStandardItem>
#include <QFileInfo>
class ResourceTreeViewSingleton: public QObject
{
Q_OBJECT
public:
~ResourceTreeViewSingleton() override;
static QSharedPointer<ResourceTreeViewSingleton>& init();
static void doDeleteLater(ResourceTreeViewSingleton *obj);
static void releaseThis();
// 单例类中需要实现的函数
bool isDirVisible(QString text);
QString changeUnit(const qint64 &size);
QString changeQStringSize(const QString &size);
bool isFile(QStandardItem * item);
QString getRelativePath(QStandardItem *item, QString relativePath);
QList<QStandardItem *> queryStandardItem(QStandardItem *topItem);
QList<QStandardItem *> queryStandardItemPush(QStandardItem *topItem);
bool saveFile(const QString &filePath, const QString &text);
QString getDefaultDeviceName(const QStandardItem *item, const QFileInfo &fileInfo);
private:
explicit ResourceTreeViewSingleton(QObject *parent = nullptr);
static QSharedPointer<ResourceTreeViewSingleton > _singleton;
static QMutex _mutex;
};
#endif // RESOURCETREEVIEWSINGLETON_H
.cpp
#include "ResourceTreeViewSingleton.h"
#include <QMutexLocker>
#include <QStandardItem>
QMutex ResourceTreeViewSingleton::_mutex;
QSharedPointer<ResourceTreeViewSingleton> ResourceTreeViewSingleton::_singleton;
ResourceTreeViewSingleton::ResourceTreeViewSingleton(QObject *parent): QObject(parent)
{
}
ResourceTreeViewSingleton::~ResourceTreeViewSingleton()
{
}
void ResourceTreeViewSingleton::doDeleteLater(ResourceTreeViewSingleton *obj)
{
obj->deleteLater();
}
void ResourceTreeViewSingleton::releaseThis()
{
_singleton.clear();
}
QSharedPointer<ResourceTreeViewSingleton> &ResourceTreeViewSingleton::init()
{
//初始化决定了它所在的线程
if (_singleton.isNull()){
QMutexLocker mutexLocker(&_mutex);
if (_singleton.isNull()){
//发现 doDeleteLater 会崩溃
_singleton = QSharedPointer<ResourceTreeViewSingleton>(new ResourceTreeViewSingleton()/*,doDeleteLater*/);
}
}
return _singleton;
}
//下面写需要实现的正常函数