QT はシングルトン モードを使用します

目次

1. シングルトンパターンの紹介

2. シングルトンモードの実装


 

1. シングルトンパターンの紹介

   Qt プロジェクトを実行しているときに、多くのクラスを使用する必要がある場合があります。たとえば、使用するクラスは A、B、C、D です。このうち、A は B、C、およびD. クラス A 非常に人気がありますが、クラス A はメモリを多く消費します。A のオブジェクトを定義するには 500M のメモリが必要です。クラス A のオブジェクトを B、C、D で定義すると、メモリの消費が考えられます。

したがって、B、C、D がそれぞれクラス A のオブジェクトを定義することは不可能です。そこで、現時点では、クラス B、C、D がすべて定義できるように、A を「グローバル変数」として定義できないか、と考えています。それにアクセスして、プログラム全体に A は 1 つだけですか?

答えは「はい」です。A を定義するときは、シングルトン モードで定義するだけです。

一般的に使用されるソフトウェア設計パターンとして、シングルトン モードは主に、システム内にインスタンスが 1 つだけ存在することを保証するために使用されます。たとえば、通常、プログラムにはログ出力インスタンスが 1 つだけ存在し、プログラムにはデータベース接続インスタンスが 1 つだけ存在します。この場合、シングルトン モードを使用することが非常に重要です。

シングルトン パターンは何に使用されますか?

前に述べたように、シングルトン パターンは次のとおりです。

(1) プログラム全体にはオブジェクトが 1 つだけあります。

(2) プログラム全体がアクセスできます。

(3) 「怠け者モード」と「腹ペコモード」に分かれる。

(4) 「遅延モード」では、シングルトンが使用される場合にのみシングルトンが作成され、それ以外の場合はオブジェクトは作成されません。

(5) 「ハングリーマン モード」では、プログラムの開始時に変数を作成する必要があります。

怠け者モードは時間を空間と交換することであり、飢えた人モードは空間を時間と交換することです。

シングルトン パターンは、大規模なプロジェクトでよく使用されます。次に例を示します。

(1) ジャーナル記録クラスはプログラム全体で 1 つだけである必要があり、2 つある場合、ログ ファイルの書き込み時に相互に「踏みつけ」ます。

(2) データベース操作と接続クラスはプログラム全体で 1 つだけでなければなりません。2 つあると問題が発生します。2 つのプロセスが同時に同じアカウントを使用するとどうなるかを確認してから、同じデータです。

シングルトン モードは、オブジェクトの繰り返し定義の問題を効果的に解決します。ミューテックス ロックと組み合わせると、複数のプロセスやスレッド間の同期と相互排他の問題も解決できます。同じ時間です。

2. シングルトンモードの実装

シングルトン パターンの設計は非常に簡単です。

cpp ファイルの例:

//这句一定要写,因为 self 是静态变量,必须要初始化值
ClassA* ClassA::self = NULL;
ClassA *ClassA::getInstance()
{
 //判断是否是第一次调用
 //假如不为 NULL,会直接 return
 if (self == NULL) {
 //防止多进程同时调用创建 2 个对象的问题
 //原理是因为是静态变量只会定义一次
 static QMutex mutex;
 //上锁
 QMutexLocker locker(&mutex);
 //在判断一次,防止其它进程抢先 new 过了
 if (self == NULL) {
 self = new ClassA;
 }
 }
 return self; //返回指针
}

h ヘッダー ファイルの例:

class ClassA : public QObject
{
 Q_OBJECT
public:
 //通过它获取 self 指针,这个函数是静态调用,不需要创建对象就可以访问
 static ClassA *getInstance(); //返回自身的指针
 //构造函数
 explicit ClassA(QObject *parent = 0);
 void hello(){ //一个普通函数
 qDebug() << "hello world";
 }
private:
 static ClassA *self; //静态指针
};
#endif // ICONFONT_H

他のクラスのメソッドを呼び出す場合:

ClassA::getInstance()->hello();

 で:

     ClassA::getInstance() はグローバル自己ポインターを取得し、これを通じて内部の関数にアクセスできます。どのクラスでも、A オブジェクトに無条件でアクセスでき、A オブジェクトを作成する必要はなく、A オブジェクトのインスタンスはグローバルに 1 つだけ存在します。

(1) クラス A に静的ポインタ self を定義します。

(2) A オブジェクトのポインタを取得するために呼び出した場合、self が空かどうかを判定し、空の場合は新しいオブジェクトを作成して self に代入し、self を返し、存在する場合は self を直接返します。

ここでは、最も一般的に使用される「遅延モード」をデモンストレーションに使用します。

cpp コードは次のとおりです (例としてデータベースを取り上げます (このクラスは複数の UI インターフェイスで使用されます))。

#include "qmqttclient.h"
#include <QMutex>
#include <QMutexLocker>
#include <QMessageBox>
//构造函数
QmqttClient::QmqttClient()
{
 
}
//这句一定要写,因为 self 是静态变量,必须要初始化值
QmqttClient* QmqttClient::mqttSelf = NULL;
QmqttClient *QmqttClient::getInstance()
{
 //判断是否是第一次调用
 //假如不为 NULL,会直接 return
 if (mqttSelf == NULL) {
 //防止多进程同时调用创建 2 个对象的问题
 //原理是因为是静态变量只会定义一次
 static QMutex mutex;
 //上锁 QMutexLocker 会锁住 mutex,当 QMutexLocker 被释放的时候自动解锁
 //locker 是局部变量,所以 getInstance 函数结束时会自动解锁
 QMutexLocker locker(&mutex);
 //在判断一次,防止其它进程抢先 new 过了
 if (mqttSelf == NULL) {
 mqttSelf = new QmqttClient;
 }
 }
 return mqttSelf; //返回指针
}

ヘッドファイル

#ifndef QMQTTCLIENT_H
#define QMQTTCLIENT_H
#include <QObject>
#include "qmqtt.h"
#include <QtCore>
class QmqttClient : public QObject{
 Q_OBJECT
public:
 //通过它获取 self 指针,这个函数是静态调用,不需要创建对像就可以访问,函数名
自定义
 //这个函数的作用是给别人获取它的静态对象 返回自身的指针
 static QmqttClient *getInstance();
// void hello(){ //一个普通函数
// qDebug() << "hello world";
private:
 QmqttClient(); //构造函数,写在 private 下,不允许 new 生成单例
 static QmqttClient *mqttSelf;//静态指针
};

他のクラスのメソッドを呼び出す場合:

QmqttClient::getInstance()->mqttClient->setHost(ui->lEditServerIP->text()); //サーバーIP QmqttClient::getInstance()->mqttClient->setPort(1883);//ポート番号

 その中には: QmqttClient::getInstance() はグローバル自己ポインターを取得します。これを通じて内部の関数にアクセスできます。どのクラスでも、A オブジェクトに無条件にアクセスでき、A オブジェクトを作成する必要はありません。オブジェクトはグローバルに次の例のみを持ちます。 注: 複数のオブジェクトをシングルトン モードにできます。

おすすめ

転載: blog.csdn.net/Lushengshi/article/details/132116935