CG@CPPBLOG

/*=========================================*/
随笔 - 76, 文章 - 39, 评论 - 137, 引用 - 0
数据加载中……

空对象模式


 
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
 

posted on 2007-12-17 21:34 cuigang 阅读(1236) 评论(2)  编辑 收藏 引用 所属分类: C/C++设计模式

评论

# re: 空对象模式  回复  更多评论   

關於 "因为Mail的缺省构造函数将自己的vptr填给了NullMail单例。"
請問博主為什麼 ?
2008-04-07 01:53 | Su, Awen

# re: 空对象模式  回复  更多评论   

@Su, Awen

new 一个对象,首先 使用 new 操作符 在堆中申请空间,然后调用构造函数初始化对象,如果有虚函数,会构造 vptr 指向 虚表, vptr 在 this 所指处。

例子中 Mail 重载了 new 操作符,返回 NullMail 单例的地址,虽然没有声明构造函数,但编译器会提供缺省构造函数,这会将 NullMail 的 指向虚表的 vptr 改为 Mail 的 vptr(new 出来的 Mail::this 实际指向 NullMail)。


2008-04-07 23:21 | cuigang

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理