图中的两个类在实现singleton时都将类的构造和析构函数的对外可视性设为private,这是实现singleton首先要注意的一个点。通过这一手段,有助于预防他人粗心地定义类实例。
图中的singleton2_t类在其构造函数中调用singleton1_t类的count_increase ()方法使计数加一。第44行的代码用于代表使用singleton2_t实例。第46行代码则显示singleton1_t类的记数信息。图2示例了该程序的运行结果。
- $ g++ main.cpp -o singleton.exe
- $ ./singleton.exe
- count = 0
是不是对于最终的显示计数为0而不是1感到奇怪?错误发生的原因在于,singleton2_t类实例的构造是先于singleton1_t类的,当singleton1_t类的实例在最后构造时会把count_变量置成0,从而覆盖singleton2_t的构造函数所引起的变更。
尽管这是一个精心设计的错误,但在大型项目中出现这类错误的可能性却并不小。因为在现实项目中,singleton1_t和singleton2_t两个类的实现很可能是在不同的源文件中,这势必造成两个类实例的初始化顺序会因链接顺序不同而不同,《揭示C++中全局类变量的构造与析构顺序》一文介绍了这是为什么。
在本例中,如果将第39行和第40行的代码进行对调就不会出现这种奇怪的现象,但这不是解决问题的终极方法。singleton更好的方法需要更改singleton的实现方法,图3示例了一种新的实现方法。
- main.c
- 00001: #include <iostream>
- 00002:
- 00003: using namespace std;
- 00004:
- 00005: class singleton1_t
- 00006: {
- 00007: public:
- 00008: static singleton1_t *instance ()
- 00009: {
- 00010: if (0 == p_instance_) {
- 00011: p_instance_ = new singleton1_t;
- 00012: }
- 00013: return p_instance_;
- 00014: }
- 00015:
- 00016: void count_increase () {count_ ++;}
- 00017: int count () const {return count_;}
- 00018:
- 00019: private:
- 00020: singleton1_t (): count_ (0) {}
- 00021: ~singleton1_t () {}
- 00022:
- 00023: static singleton1_t *p_instance_;
- 00024: int count_;
- 00025: };
- 00026:
- 00027: class singleton2_t
- 00028: {
- 00029: public:
- 00030: static singleton2_t *instance ()
- 00031: {
- 00032: if (0 == p_instance_) {
- 00033: p_instance_ = new singleton2_t;
- 00034: }
- 00035: return p_instance_;
- 00036: }
- 00037:
- 00038: private:
- 00039: singleton2_t () {singleton1_t::instance ()->count_increase ();}
- 00040: ~singleton2_t () {}
- 00041:
- 00042: static singleton2_t *p_instance_;
- 00043: };
- 00044:
- 00045: singleton2_t *singleton2_t::p_instance_ = 0;
- 00046: singleton1_t *singleton1_t::p_instance_ = 0;
- 00047:
- 00048: int main ()
- 00049: {
- 00050: singleton2_t::instance ();
- 00051: cout << "count = " << singleton1_t::instance ()->count () << endl;
- 00052: return 0;
- 00053: }
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-21891-2.html
大发
没钱看