您的位置:首页 > 编程语言 > C语言/C++

C++编程思想(卷二):设计模式:单件

2009-12-10 15:29 513 查看
单件(Singleton):

例:允许一个类有且仅有一个实例的方法

#include <iostream>
using namespace std;
class Singleton {
static Singleton s;
int i;
Singleton(int x) : i(x) { }
Singleton& operator=(Singleton&);  // Disallowed
Singleton(const Singleton&);       // Disallowed
public:
static Singleton& instance() { return s; }
int getValue() { return i; }
void setValue(int x) { i = x; }
};
Singleton Singleton::s(47);
int main() {
Singleton& s = Singleton::instance();
cout << s.getValue() << endl;
Singleton& s2 = Singleton::instance();
s2.setValue(9);
cout << s.getValue() << endl;
}


创建一个单件模式的关键是防止客户程序员获得任何控制其对象生存期的权利。为了做到这一点,声明所有的构造函数为私有,并且防止编译器隐式生成任何构造函数。拷贝构造函数和赋值操作符被声明为私有,以便防止任何这类复制的动作产生。

单件的变体:

一个类中的任何static静态成员对象都表示一个单件:有且仅有一个对象被创建。

通过定义一个静态对象来控制初始化顺序来延迟对象的初始化,直到在该函数第一次被调用时才进行初始化。如果该函数返回一个静态对象的引用,就可以达到单件的效果。这样的函数必须不是内联的,函数的实现必须分开,这是为了试图控制初始化的顺序。

因此可以对上面的代码做如下修改:

#include <iostream>
using namespace std;
class Singleton {
int i;
Singleton(int x) : i(x) { }
void operator=(Singleton&);
Singleton(const Singleton&);
public:
static Singleton& instance() {
static Singleton s(47);
return s;
}
int getValue() { return i; }
void setValue(int x) { i = x; }
};
int main() {
Singleton& s = Singleton::instance();
cout << s.getValue() << endl;
Singleton& s2 = Singleton::instance();
s2.setValue(9);
cout << s.getValue() << endl;
}


这种方法称作惰性初始化,只在创建对象的代价不大,并且并不总是需要它的情况下才有意义。

单件另一个变体:

例:将一个对象的“单件角”从其实现中分离出来

#include <iostream>
using namespace std;
template<class T> class Singleton {
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
protected:
Singleton() {}
virtual ~Singleton() {}
public:
static T& instance() {
static T theInstance;
return theInstance;
}
};
// A sample class to be made into a Singleton
class MyClass : public Singleton<MyClass> {
int x;
protected:
friend class Singleton<MyClass>;
MyClass() { x = 0; }
public:
void setValue(int n) { x = n; }
int getValue() const { return x; }
};
int main() {
MyClass& m = MyClass::instance();
cout << m.getValue() << endl;
m.setValue(1);
cout << m.getValue() << endl;
}


MyClass通过下面3个步骤产生一个单件:

声明其构造函数为私有或保护的

声明类Singleton<MyClass>为友元

从Singleton<MyClass>派生出MyClass。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: