今天在看《C++ Strategies and Tactics》的时候发现了一段非常有意思的代码:
1 class Complex_rep { 2 private: 3 friend class Complex; 4 double real_d; 5 double image_d; 6 Complex_rep(double r, double i) : real_d(r), image_d(i) { 7 8 } 9 };10 11 class Complex {12 private:13 Complex_rep *rep;14 public:15 Complex(double r, double i)16 :rep(new Complex_rep(r, i)) {}17 ~Complex() { delete rep; }18 };
可以看到Complex表示复数(complex)数据结构,但是有意思的是数据成员(复数的实部和虚部)并没有存储在Complex内部,而是在一个Complex_rep类中。在Complex_rep中将Complex声明为友元类,这样Complex就可以访问Complex_rep中的所有成员和方法。同时将Complex_rep的构造函数声明为private类型,这样在类体外部就不能Complex_rep的实例,只能通过友元类Complex创建。
这样表示的意义是说,Complex_rep是类Complex所独有的,只能通过Complex创建和访问,别的任何类都不能创建Complex_rep实例。
(往下看第三章的时候才知道这种方法在C++中叫做 句柄 (handle))。
将构造函数声明为private的技巧在设计模式的“Singleton模式”也有应用,一个Singleton类定义如下:
1 class Singleton { 2 public: 3 static Singleton* instance(); 4 protected: 5 Singleton(); 6 private: 7 static Singleton* _instance; 8 }; 9 10 Singleton* Singleton::_instance = 0;11 12 Singleton* Singleton::instance() {13 if(_instance == 0) {14 _instance = new Singleton;15 }16 return _instance;17 }
客户仅通过instance()成员函数访问这个单件。变量_instance初始化为0,而静态成员函数interface()返回其变量值,如果其值为0则用唯一实例初始化它。instance()使用惰性(lazy)初始化:_instance直到第一次被访问时才会创建和保存。