分类: C/C++
2008-08-07 17:42:30
话说一群土著人生活地球的某个不为人知的地方,他们过着和谐、快乐的日子。但是好景不长,一只从天上掉下来的玻璃瓶打破了这美好的时光。这只玻璃瓶用处非常广泛,有的土著人用它来砸地瓜,有的用它来吹口哨,有的用它来擀蛇皮……,渐渐地大家干活、娱乐都离不开它了,于是产生了争抢使用可乐瓶的情况,为了获得原有的和谐气氛,一个土著人决定扔掉这个瓶子……
剧情讲完了,我们先为这个瓶子定义一个类:
class CGlassBottle { private: CGlassBottle(); public: virtual ~CGlassBottle(); public: static BOOL OnKnock();//砸 static BOOL OnBlow();//吹 static BOOL OnRoll();//擀 protected: static BOOL s_bUsed;//是否正在被使用 };我们定义一个土著人A类,假设他只用玻璃瓶砸地瓜:
class A//土著人A { public: void UseBottle() { CGlassBottle::OnKnock(); }; };我们再定义一个土著人B类,假设他只用玻璃瓶吹口哨:
class B//土著人B { public: void UseBottle() { CGlassBottle::OnBlow(); }; };现在我们定义土著人A、B类的对象,让他们执行UseBottle:
int main(int argc, char* argv[]) { A a; B b; a.UseBottle();//执行Knock b.UseBottle();//执行blow return 0; }我们来执行一下,看看结果:
class CNumFormat { private: CNumFormat(); public: static CString From2TO10(LPCTSTR lpszTxt2); static CString From2TO16(LPCTSTR lpszTxt2); static CString From10TO2(LPCTSTR lpszTxt2); static CString From10TO16(LPCTSTR lpszTxt2); static CString From16TO2(LPCTSTR lpszTxt2); static CString From16TO10(LPCTSTR lpszTxt2); };在本例子中的CGlassBottle类,这样用也是可以的,但我们还可以把它设计得更好。在《深入浅出设计模式》中是这样定义单件模式的:确保一个类只有一个实例,并提供全局访问点。下面我们根据该定义对CGlassBottle类进行改进:
class CGlassBottle { private: CGlassBottle(); public: virtual ~CGlassBottle(); public: bool OnKnock();//砸 bool OnBlow();//吹 bool OnRoll();//擀 public: static CGlassBottle s_GlassBottle;//定义 protected: bool m_bUsed;//是否正在被使用 };对土著人A、B类进行相应的修改:
class A//土著人A { public: void UseBottle() { CGlassBottle::s_GlassBottle.OnKnock(); }; }; class B//土著人B { public: void UseBottle() { CGlassBottle::s_GlassBottle.OnBlow(); }; };很多时候我们不希望s_GlassBottle暴露出来,而更希望通过函数调用来获取,于是增加一个获取s_GlassBottle的函数,同时把GlassBottle搞成私有静态成员,具体如下:
class CGlassBottle { private: CGlassBottle(); public: virtual ~CGlassBottle(); public: bool OnKnock();//砸 bool OnBlow();//吹 bool OnRoll();//擀 public: static CGlassBottle* GetInstance() { return &s_GlassBottle; } private: static CGlassBottle s_GlassBottle;//定义 protected: bool m_bUsed;//是否正在被使用 };土著人 A、B类在UseBottle()时进行如下修改:
class A//土著人A { public: void UseBottle() { CGlassBottle::GetInstance()->OnKnock(); }; }; class B//土著人B { public: void UseBottle() { CGlassBottle::GetInstance()->OnBlow(); }; };可能许多朋友都听说过延迟实例化这个概念,那我们这里也玩玩这个概念:
class CGlassBottle { private: CGlassBottle(); public: virtual ~CGlassBottle(); public: bool OnKnock();//砸 bool OnBlow();//吹 bool OnRoll();//擀 public: static CGlassBottle* GetInstance() { static CGlassBottle s_GlassBottle;//定义 return &s_GlassBottle; } protected: bool m_bUsed;//是否正在被使用 };其实我也偏好这种用法,不知道在多线程下面会不会有问题(我只在单线程下玩,所以还没有发现过问题)。但是你会发现在调用GetInstance()的时候必须要在前面加上CGlassBottle::,在调用时像下面这样:
CGlassBottle::GetInstance()->OnKnock();这是不是会让人觉得啰嗦呢,至少对我来说很啰嗦,但我们还可以像下面这么处理:
#define GetGlassBottle() CGlassBottle::GetInstance()用的时候就这么用“GetGlassBottle()->Knock();”,当然还可以对CGlassBottle进行改进,不知道这叫不叫改进:
class CGlassBottle { private: CGlassBottle(); public: virtual ~CGlassBottle(); public: bool OnKnock();//砸 bool OnBlow();//吹 bool OnRoll();//擀 private: friend CGlassBottle* GetGlassBottle(); static CGlassBottle* GetInstance() { static CGlassBottle s_GlassBottle;//定义 return &s_GlassBottle; } protected: bool m_bUsed;//是否正在被使用 }; inline CGlassBottle* GetGlassBottle() { return CGlassBottle::GetInstance(); }现在可以这样用了:
GetGlassBottle()->OnKnock();这样看起来是不是舒服多了。
class CGlassBottle { private: CGlassBottle(); public: virtual ~CGlassBottle(); public: bool OnKnock();//砸 bool OnBlow();//吹 bool OnRoll();//擀 private: friend CGlassBottle* GetGlassBottle(); protected: bool m_bUsed;//是否正在被使用 }; inline CGlassBottle* GetGlassBottle() { static CGlassBottle s_GlassBottle;//定义 return &s_GlassBottle; }文章到此结束,如有不妥之处,请来信告知。