C++ でシングルトンを作成する方法

C Deshingurutonwo Zuo Chengsuru Fang Fa



C++ では、シングルトンは、プログラム全体でクラスの唯一のインスタンスの存在を保証し、その特定のインスタンスへのグローバル アクセス ポイントを提供する設計原則です。

シングルトン パターンは、データベース接続、ロガー、構成マネージャーなど、グローバルにアクセスする必要がある単一の共有リソースが必要な場合によく使用されます。単一インスタンスを強制することにより、プログラムの複数の部分が同じオブジェクトにアクセスして変更できるようになり、データの一貫性が促進され、グローバル変数の必要性が減ります。シングルトンは、頻繁に使用されるオブジェクトや作成にコストがかかるオブジェクトを保存し、アプリケーション全体で再利用するオブジェクト キャッシュとして使用できます。このアプローチは、冗長なオブジェクトの作成と初期化を回避することでパフォーマンスを向上させるのに役立ちます。

この記事では、シングルトンの作成について説明し、C++ プログラムでシングルトンをスタイル設定する例を示します。







例 1: 即時初期化を使用した単純なシングルトンの作成

早期初期化を伴う単純なシングルトンは、クラスのインスタンスが 1 つだけ作成されることを保証する設計パターンであり、静的初期化中に積極的に作成されます。



積極的な初期化を使用して単純なシングルトンを作成するための基本的なコード スニペットを示します。プログラムから始めましょう:



#include

クラスシングルトン {
プライベート :
静的 シングルトン * 実例 ;
シングルトン ( ) { }
公共 :
静的 シングルトン * インスタンスの取得 ( ) {
戻る 実例 ;
}
} ;


シングルトン * シングルトン :: 実例 = 新しいシングルトン ( ) ;

整数 主要 ( ) {

シングルトン * シングルトンインスタンス1 = シングルトン :: インスタンスの取得 ( ) ;

シングルトン * シングルトンインスタンス2 = シングルトン :: インスタンスの取得 ( ) ;

標準 :: コート << 'singletonletonInstance1: ' << シングルトンインスタンス1 << 標準 :: 終わり ;

標準 :: コート << 'singletonletonInstance2: ' << シングルトンインスタンス2 << 標準 :: 終わり ;

戻る 0 ;

}

このコードには、「std::cout」などの入出力ストリームを操作する機能を提供する ヘッダーが含まれています。





ヘッダー ファイルをインクルードした後、シングルトン パターンの実装を表す「Singleton」クラスを定義します。これにはプライベート コンストラクターと「instance」という名前のプライベート静的メンバー変数があります。

次に、getInstance()関数が「Singleton」クラスのパブリック静的メンバー関数として実装されます。静的メンバー変数インスタンスに格納されているシングルトンのインスタンスを返します。静的メンバー変数インスタンスは、「Singleton* Singleton::instance = new Singleton();」によってクラスの外で定義および初期化されます。この行は、静的初期化中に「Singleton」クラスのインスタンスを積極的に初期化します。



main() 関数では、2 つのポインター「singletonInstance1」と「singletonInstance2」を宣言し、Singleton::getInstance() を呼び出して返される値を割り当てます。インスタンスは積極的に初期化されるため、両方のポインターは同じインスタンスを指します。 「std::cout」ステートメントは、「<<」演算子と「std::endl」を使用して、「singletonInstance1」と「singletonInstance2」のメモリ アドレスをコンソールに出力します。

コードは、プログラムの実行が成功したことを示す「return 0」で終わります。

このコードを実行すると、出力は次のようになります。

出力には、「singletonInstance1」と「singletonInstance2」のメモリ アドレスが表示されます。どちらのポインタにも Singleton::getInstance() で取得した同じインスタンスが割り当てられているため、同じメモリ アドレスを持ちます。これは、シングルトン パターンがクラスのインスタンスが 1 つであること、および今後の getInstance() の呼び出しが常に同じインスタンスになることを保証する方法を示しています。

例 2: 遅延初期化を使用したシングルトン パターンの実装

このデモでは、遅延初期化によるシングルトン パターンの実装について説明し、main() 関数でのその使用法を示します。コード スニペットの段階的な説明は、このプログラムの後に提供されます。

#include

クラスシングルトン {

プライベート :

静的 シングルトン * 実例 ;

シングルトン ( ) {

標準 :: コート << 「シングルトンインスタンスが作成されました。」 << 標準 :: 終わり ;

}

公共 :

静的 シングルトン * インスタンスの取得 ( ) {

もし ( 実例 == nullptr ) {

実例 = 新しいシングルトン ( ) ;

}

戻る 実例 ;

}

空所 showMessage ( ) {

標準 :: コート << 「シングルトンからこんにちは!」 << 標準 :: 終わり ;

}

~シングルトン ( ) {

標準 :: コート << 「シングルトンインスタンスが破壊されました。」 << 標準 :: 終わり ;

}

} ;

シングルトン * シングルトン :: 実例 = nullptr ;

整数 主要 ( ) {

シングルトン * シングルトンインスタンス1 = シングルトン :: インスタンスの取得 ( ) ;

シングルトンインスタンス1 -> showMessage ( ) ;

シングルトン * シングルトンインスタンス2 = シングルトン :: インスタンスの取得 ( ) ;

シングルトンインスタンス2 -> showMessage ( ) ;

戻る 0 ;

}

プログラムは、入出力タスクを実行するための ヘッダー ファイルを追加することから始まります。次に、「Singleton」クラスを宣言して定義します。クラスの唯一のインスタンスは、「instance」という名前のプライベート静的メンバー変数内に保持されます。

「Singleton」クラスのコンストラクターが呼び出されるたびに、「Singleton」クラスのインスタンスが生成されます。 「std::cout << … << std::endl;」を使用して、「シングルトン インスタンスが作成されました」というメッセージをコンソールに出力します。コンストラクターはデフォルトのコンストラクターであるため、パラメーターを持ちません。引数なしで Singleton() として定義されます。これをプライベートとして宣言します。これは、クラス内からのみ呼び出すことができることを意味します。これにより、「Singleton」クラスの直接インスタンス化が防止され、インスタンスを取得する唯一の方法が getInstance() 関数を使用することになります。

「Singleton」クラスの getInstance() メソッドは、パブリックな静的メンバー関数として宣言されます。これは、シングルトン インスタンスへのアクセスを確立し、許可する役割を果たします。 getInstance() 内で、インスタンスが「nullptr」かどうかを確認します。存在する場合は、インスタンスがまだ存在していないことを意味し、プライベート コンストラクターを使用して「Singleton」クラスの新しいオブジェクトをインスタンス化します。

showMessage() 関数は、「Hello from Singleton!」を表示する単純なメンバー関数です。メッセージ。シングルトンのデストラクタを定義します。これは、プログラムが終了して「シングルトン インスタンスが破棄されました」と出力するときに暗黙的に呼び出されます。シングルトン インスタンスが破棄されたことを示すメッセージ。静的メンバー変数インスタンスは、最初は「nullptr」として定義されています。

int main() は main() 関数の定義を開始します。次に、「Singleton* singletonInstance1 = Singleton::getInstance();」となります。 「Singleton」クラスの getInstance() 関数を呼び出して、シングルトン インスタンスへのポインタを取得します。このポインタを「singletonInstance1」変数に割り当てます。

その後、「singletonInstance1->showMessage();」矢印演算子 (->) を使用して、「singletonInstance1」ポインターの showMessage() 関数を呼び出します。この関数は、その中で指定されたメッセージをコンソールに表示します。その後、「Singleton* singletonInstance2 = Singleton::getInstance();」 getInstance() 関数を再度呼び出して、シングルトン インスタンスへの別のポインタを取得します。今回は、ポインタを「singletonInstance2」変数に割り当てます。 「singletonInstance2->showMessage();」 「singletonInstance2」ポインタで showMessage() 関数を呼び出します。 「シングルトンからこんにちは!」を表示する機能です。コンソールに再度メッセージを送信します。

最後に「0を返す」。 main() 関数の終了を示し、プログラムはプログラムの実行が成功したことを示す値 0 を返します。

前に説明したコード スニペットの出力は次のとおりです。

この結果は、「Singleton」クラスがインスタンスを 1 つだけ作成することを保証し、さらに getInstance() 関数を呼び出しても同じインスタンスが確実に生成されることを確認します。

結論

C++ でシングルトンを作成することは、非常に便利な概念です。この投稿では、最初にシングルトンの紹介セクションについて説明しました。さらに、C++ でシングルトンを実装するために 2 つの例が作成されます。最初の図は、積極的なシングルトン初期化の実装を示しています。一方、シングルトン パターンの遅延初期化の実装は、この記事の 2 番目の例で提供されています。さらに、対応するプログラムについて、生成された出力のスナップショットも表示されます。