4.6.2 boost.serialzation的单件实现
在序列化库serialization中有另一个单件实现类:singleton,它位于名字空间boost::serialization,为了使用singleton,需要包含头文件<boost/serialization/ singleton.hpp>,即:
- #include <boost/serialization/singleton.hpp>
- using boost::serialization::singleton;
类摘要
singleton的类简要声明如下:
- template <typename T>
- class singleton : public boost::noncopyable
- {
- public:
- static const T & get_const_instance();
- static T & get_mutable_instance();
- };
singleton与pool.singleton_default基本相同,对模板参数T也有同样的要求(具有缺省构造函数,构造析构不抛异常),但访问单件实例的成员函数却有区分,分为了常对象和可变对象两个函数。这种区分是出于线程安全的考虑,常对象单件总是线程安全的,因为它不会改变内部状态,而可变对象单件则不是线程安全的,可能会发生线程竞争问题。
用法
singleton可以如pool.singleton_default一样使用模板参数的方式来使用:
- #include <boost/serialization/singleton.hpp>
- using boost::serialization::singleton;
-
- class point{...}
- int main()
- {
- cout << "main() start" << endl;
- typedef singleton<point> origin; //单件类定义
-
- origin::get_const_instance().print(); //常对象
- origin::get_mutable_instance().print(); //可变对象
-
- cout << "main() finish" << endl;
- }
代码中需要注意的是类名singleton,还有就是访问实例的函数不是instance(),而是get_ const_instance()和get_mutable_instance(),程序运行结果与pool.singleton_ default完全相同。
除了这种模板方式,serialization.singleton还可以通过继承的方式来使用,把singleton作为单件类的基类,并把单件类作为singleton的模板参数:
- #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;
- }
这段代码与模板参数的用法仅有很小的不同,最重要的变化在于point类的基类声明处public继承singleton<point>(如果读者不熟悉泛型编程(www.cppentry.com),可能会对这种父类中使用子类的形式有些困惑),因此point继承了singleton的所有能力,包括不可拷贝和单件。
与模板参数方式相比,继承方式实现单件模式更为彻底一些(很像noncopyable的用法),使被单件化的类成为了一个真正的单件类,而模板参数方式则更"温和"一些,它包装(wrap)了被单件化的类,对原始类没有任何影响。