Martin Flower在《重构》里提到空对象模式,对于从容器中查找失败需要返回引用时,可以使用,同时我觉的对于空指针调用也有一定作用,试举一例:
1 #include <iostream>
2
3 class Mail{
4 public:
5 virtual void print()
6 {std::cout<<"Hello!"<<std::endl;};
7 void* operator new(size_t);
8 };
9
10 class NullMail{
11 NullMail(){};
12 static NullMail inst;
13 public:
14 virtual void print(){
15 using namespace std;
16 cout<<"error! You can't access a NULL object!"<<endl;
17 }
18 static NullMail& GetInst(){return inst;};
19 };
20
21 NullMail NullMail::inst;
22
23 void* Mail::operator new(size_t){
24 return &NullMail::GetInst();
25 }
26
27 Mail* GetMailPtr(){
28 return NULL;
29 }
30
31 Mail& GetMailRef(){
32 return (Mail&)NullMail::GetInst();
33 }
34
35 //
36
37 Mail* ptr_Mail = GetMailPtr();
38 Mail& ref_Mail = GetMailRef();
39 //ptr_Mail->print();
40 ref_Mail.print();
当我们返回一个空指针给调用者,如果他没有判断,那就会发生系统崩溃,而我们返回一个空对象的引用就可以避免这一点。
另外一个附加的有趣现象,你认为下面的调用会输出什么信息?
1
2 ptr_Mail = new Mail;
3 ptr_Mail ->print();
4 ref_Mail.print();
正确的答案是:
1 Hello!
2 Hello!
因为Mail的缺省构造函数将自己的vptr填给了NullMail单例。
=====================
一个问题,是不是Mail的每个公共接口,NullMail都要去实现一下? --th
//除非实在没有必要,的确应当实现一下所有的公有虚方法。cuigang,2007-11-08
=====================
“对于从容器中查找失败需要返回引用时”,下午刚刚碰到一个这样的问题。 jb