シングルトン
シングルトンはシングルトン モードであり、このモードを実装するクラスは、プログラム ライフ サイクル内でインスタンスを 1 つだけ持つことができます。シングルトン パターンは、多くの実用的な用途があり、広く徹底的に研究されている便利な作成パターンです。
シングルトン モードは非常に重要ですが、残念ながら現在 Boost には専用のシングルトン ライブラリはなく、名前空間 boost::serialization にあるシリアル化ライブラリに不完全な実装があるだけです。
シングルトンを使用するには、ヘッダー ファイル <boost/serialization/singleton.hpp> をインクルードする必要があります。つまり、次のとおりです。
#include <boost/serialization/singleton.hpp>
using boost::serialization::singleton;
授業概要
template <typename T>
class singleton : public boost::noncopyable
{
public:
static const T & get_const_instance();
static T & get_mutable_instance();
};
singleton は、テンプレート パラメーター T をシングルトン クラスとして実装します。型 T の要件は、デフォルトのコンストラクターがあり、シングルトンは main() の前後で構築および破棄されるため、構築および破棄中に例外をスローできないことです。が発生しても捕まえることはできません。
singleton は、シングルトン インスタンスにアクセスするための 2 つの静的メンバー関数を提供し、それぞれ定数オブジェクトと変数オブジェクトを取得できます。この区別はスレッド セーフの考慮事項によるもので、定数オブジェクト シングルトンは内部状態を変更しないため常にスレッド セーフですが、可変オブジェクト シングルトンはスレッド セーフではなく、スレッド競合の問題が発生する可能性があります。
使用法
シングルトンの作成と破棄を示すために、次のコードではコンストラクターとデストラクターを追加します。
class point
{
public:
point(int a = 0, int b = 0, int c = 0) :x(a), y(b), z(c) //构造函数
{
cout << "point ctor" << endl;
}
~point() //析构函数
{
cout << "point dtor" << endl;
}
...
};
シングルトンの使い方は非常に簡単で、シングルトンにしたいクラスをテンプレートパラメータとして指定するだけで、次の作業は自動的にシングルトンによって完了します。おそらく、唯一の不便な点は型名が長いことですが、これは typedef を使用して簡素化できます。
#include <boost/serialization/singleton.hpp>
using boost::serialization::singleton;
int main()
{
cout << "main() start" << endl;
typedef singleton<point> origin; //单件类定义
point::get_const_instance().print(); //常对象
point::get_mutable_instance().print(); //可变对象
cout << "main() finish" << endl;
}
コード内で注意が必要なのは、クラス名がsingletonであることと、インスタンスにアクセスする関数がよく使われるinstance()ではなく、get_const_instance()とget_mutable_instance()であることです。
このテンプレート メソッドに加えて、シングルトン クラスの基本クラスとしてシングルトンを使用し、シングルトン クラスをシングルトンのテンプレート パラメーターとして使用して、継承を通じてシングルトンを使用することもできます。
#include <boost/serialization/singleton.hpp>
using boost::serialization::singleton;
class point : public singleton<point> //注意这里
{
...}
int main()
{
cout << "main() start" << endl;
point::get_const_instance().print(); //常对象
point::get_mutable_instance().print(); //可变对象
cout << "main() finish" << endl;
}
このコードは、テンプレート パラメーターの使用法とわずかに異なるだけです。最も重要な変更は、ポイント クラスの基底クラス宣言のパブリック継承です (読者がsingleton<point>
ジェネリック プログラミングに慣れていない場合、サブクラスの使用について混乱するかもしれません)このような親クラスでは、形式が少しわかりにくいため)、point は、コピー不可およびシングルトンを含むシングルトンのすべての機能を継承します。
テンプレート パラメーター メソッドと比較して、継承メソッドはシングルトン モードをより徹底的に実装し (noncopyable の使用法とよく似ています)、シングルトン化されたクラスを実際のシングルトン クラスにします。一方、テンプレート パラメーター メソッドはより「穏やか」で、シングルトン化されたクラスをラップします。クラス、元のクラスには影響しません。
コード例
#include <iostream>
using namespace std;
#include <boost/serialization/singleton.hpp>
using boost::serialization::singleton;
//
class point : public singleton<point>
{
int x, y, z;
public:
point(int a = 0, int b = 0, int c = 0) :x(a), y(b), z(c)
{
cout << "point ctor" << endl;
}
~point()
{
cout << "point dtor" << endl;
}
void print()const
{
cout << x << "," << y << "," << z << endl;
}
};
typedef singleton<point> origin;
//
int main()
{
cout << "main() start" << endl;
origin::get_const_instance().print();
origin::get_mutable_instance().print();
point::get_const_instance().print();
point::get_mutable_instance().print();
cout << "main() finish" << endl;
}