<读书笔记> Thinking in python (Python 设计模式) 1. Singlton的c++与python的实现
1.由于python的天然的泛型特征,python 中沒有接口繼承,所有的繼承都是實現繼承,子類為了繼承父類的實現。
?
2.Singlton 單件模式
- singlton in c++
????? 下面看一個最簡單的C++實現,它做到的是通過
????? 類static變量,以及將默認構造函數私有化,
????? 從而使得只能有一個GlobalClass的實體存在,
?? ? ??1?#include?<iostream>
?2?using?namespace?std;?3?
?4?class?GlobalClass?{
?5?????public:
?6?????????static?GlobalClass*?instance();
?7?????????static?void?create();
?8?????????static?void?destroy();
?9?????????void?print()?{
10?????????????cout?<<?"haha"?<<?endl;
11?????????}
12?????private:
13?????????static?GlobalClass*?s_instance;
14?????????GlobalClass();
15?????????~GlobalClass(){
16?????????????//destroy();
17?????????????cout?<<?"destruct"?<<?endl;
18?
19?????????}
20?};
21?
22?GlobalClass*?GlobalClass::s_instance?=?NULL;
23?
24?GlobalClass::GlobalClass()?{
25?????cout?<<?"construct?global?class"?<<?endl;
26?}
27?//GloblaClass::~GlobalClass()?{
28?//????destroy();
29?//????cout?<<?"destruct"?<<?endl;
30?//}
31?GlobalClass*?GlobalClass::instance()?{
32?????return?s_instance;
33?}
34?
35?void?GlobalClass::create()?{
36?????if?(!s_instance)
37?????????s_instance?=?new?GlobalClass();
38?}
39?
40?void?GlobalClass::destroy()?{
41?????delete?s_instance;
42?????s_instance?=?NULL;
43?????cout?<<?"delete?ok"?<<?endl;
44?}
45?
46?int?main(int?argc,?char?*argv[])
47?{
48?????//GlobalClass?my_global_class; ?//can't create by this
49?????GlobalClass::create();
50?????GlobalClass*?p_global_class?=?GlobalClass::instance();
51?????p_global_class->print();
52?????GlobalClass::destroy();
53?????return?0;
54?} //result construct global class haha destruct delete ok
剛剛想到effective c++第四款,提到的的利用函數內部local static變量的方法。這樣也可以給出一種Siglton的實現 ??1?//file?singlton.h
??2?
??3?#ifndef?_SINGLTON_H_
??4?#define?_SINGLTON_H_
??5?#include?<iostream>
??6?using?namespace?std;
??7?
??8?class?GlobalClass?{
??9?????public:
?10?????????static?GlobalClass&?instance(int?weight?=?3){
?11?????????????static?GlobalClass?global_object(weight);
?12?????????????return?global_object;
?13?????????}
?14?????????void?print()?{
?15?????????????cout?<<?"haha"?<<?this?<<?endl;
?16?????????????cout?<<?m_weight?<<?endl?<<?endl;
?17?????????}
?18?????????~GlobalClass(){
?19?????????????cout?<<?"destruct"?<<?this?<<?endl;
?20?
?21?????????}
?22?????????void?addOne()?{
?23?????????????m_weight?+=?1;
?24?????????}
?25?
?26?????private:
?27?????????GlobalClass()?{
?28?????????????cout?<<??"construct?global?class"?<<?this?<<?endl;
?29?
?30?????????}
?31?????????GlobalClass(int?weight):m_weight(weight){?cout?<<?"construct?global?class?with?weight"?<<?this?<<?endl;}
?32?????????GlobalClass&?operator=(?const?GlobalClass&);
?33?????????GlobalClass(const?GlobalClass&);
?34?????????int?m_weight;
?35?};
?36?#endif
?37?
?38?
?39?//file?use_singlton.h
?40?#ifndef?USE_SIGLTON_H
?41?#define?USE_SIGLTON_H
?42?
?43?#include?"singlton.h"
?44?void?useSinglton();
?45??
?46?#endif
?47?
?48?//file?use_singlton.cc
?49?#include?<iostream>
?50?#include?"use_singlton.h"
?51?using?namespace?std;
?52?void?useSinglton()?{
?53?????GlobalClass&?p_global_class?=?GlobalClass::instance(16);
?54?????p_global_class.print();
?55?????p_global_class.addOne();
?56?????p_global_class.print();
?57?
?58?????GlobalClass&?p_global_class2?=?GlobalClass::instance(46);
?59?????p_global_class2.print();
?60?????p_global_class2.addOne();
?61?????p_global_class2.print();
?62?}
?63?
?64?//file?test_singlton.cc
?65?#include?<iostream>
?66?#include?"singlton.h"
?67?#include?"use_singlton.h"
?68?using?namespace?std;
?69?
?70?int?main(int?argc,?char?*argv[])
?71?{
?72?????cout?<<?"use?singlton"?<<?endl;
?73?????useSinglton();
?74?
?75?????cout?<<?"wa?ha?ha?"?<<?endl;
?76?????GlobalClass&?p_global_class?=?GlobalClass::instance(4);
?77?????p_global_class.print();
?78?????p_global_class.addOne();
?79?????p_global_class.print();
?80?
?81?????GlobalClass&?p_global_class2?=?GlobalClass::instance(8);
?82?????p_global_class2.print();
?83?????p_global_class2.addOne();
?84?????p_global_class2.print();
?85?
?86?????cout?<<?"ha?ha?wa"?<<?endl;
?87?????useSinglton();????
?88?
?89?????return?0;
?90?}
?91?
?92?//allen:~/study/design_pattern/singlton_test$?g++?-g?-o?test_singlton??test_singlton.cc?use_singlton.cc?
?93?allen:~/study/design_pattern/singlton_test$?./test_singlton?
?94?use?singlton
?95?construct?global?class?with?weight0x804a5c0
?96?haha0x804a5c0
?97?16
?98?
?99?haha0x804a5c0
100?17
101?
102?haha0x804a5c0
103?17
104?
105?haha0x804a5c0
106?18
107?
108?wa?ha?ha?
109?haha0x804a5c0
110?18
111?
112?haha0x804a5c0
113?19
114?
115?haha0x804a5c0
116?19
117?
118?haha0x804a5c0
119?20
120?
121?ha?ha?wa
122?haha0x804a5c0
123?20
124?
125?haha0x804a5c0
126?21
127?
128?haha0x804a5c0
129?21
130?
131?haha0x804a5c0
132?22
133?
134?destruct0x804a5c0
135? 用local static的這個方法也保證了只有一個實例的存在,不過僅供學習吧,不如第一種方案,畢竟有一個類類型的static變量的存在, 而且它只能在main介紹的時候才會被析構,上面的我們可以隨時主動去析構對象。
Singlton的基本思想很簡單,但是用C++實現,關于資源的釋放,何時釋放還是感覺很別扭的。 下面是網上找到的一個基于模版的singlton實現,可以方便的復用該框架,同時利用了shared_ptr,無需操心釋放動態內存。另外給出一個OPEMESH中的singlton模版的實現,它也是使用了產生一個類類型的static變量(用戶需要的時候才會產生出來)。這兩種方式都會在main結束后析構掉siglton對象資源,如shared_ptr自動釋放 new的資源,而OPEMESH的方法static的類對象會銷毀(調用起析構函數).//使用shared_ptr實現的singlton模版類?1?#include?<iostream>
?2?#include?<tr1/memory>
?3?using?namespace?std;
?4?using?namespace?std::tr1;
?5?template?<typename?T>
?6?class?Singlton?{
?7?????public:
?8?????????static?T*?instance();
?9?????????static?void?create();
10?????????void?print()?{
11??????????????cout?<<?"haha"?<<?endl;
12?????????}
13?????????~Singlton()?{
14?????????????cout?<<?"destruct?singlton"?<<?endl;
15?????????}
16?????protected:
17?????????Singlton();
18?????//private:
19?????protected:
20?????????static?shared_ptr<T>?s_instance;?
21?????????//Singlton();
22?};
23?template?<typename?T>
24?shared_ptr<T>?Singlton<T>::s_instance;
25?
26?template?<typename?T>
27?Singlton<T>::Singlton()?{
28?????cout?<<?"construct?singlton"?<<?endl;
29?}
30?
31?template?<typename?T>
32?T*?Singlton<T>::instance()?{
33?????return?s_instance.get();
34?}
35?
36?template?<typename?T>
37?void?Singlton<T>::create()?{
38?????if?(!s_instance.get())
39?????????s_instance.reset(new?T);
40?
41?}
42?
43?//?well?這里注意,我理解為Singlton<T>::create()?應該可以調用?MySinglton的私有函數,但事實上不行
44?//?因為理論上?還是調用基類的函數?Singlton<MySinglton>::create()
45?//class?MySinglton?:?public?Singlton<MySinglton>?{
46?//????//private:
47?//????public:
48?//????????MySinglton(){
49?//????????????cout?<<?"construct?my?singlton"?<<?endl;
50?//????????}
51?//
52?//};
53?class?MySinglton?:?public?Singlton<MySinglton>?{
54?????????friend??class?Singlton<MySinglton>;
55?????private:
56?????????MySinglton(){
57?????????????cout?<<?"construct?my?singlton"?<<?endl;
58?????????}
59?????????MySinglton?*?MyInstance()?{
60?????????????return?s_instance.get();
61?????????}
62?};
63?
64?//or?can?directyly?define?one?class?like?MyClass1,?and?to?not?consider?siglton?part,
65?//than?use?Singlton<MyClass1>??is?OK.?May?be?typedef?Singlton<MyClass1>?MyClass1Singlton?
66?//and?use?MyClass1Siglton
67?int?main(int?argc,?char?*argv[])
68?{
69????????
70?????MySinglton::create();
71?????MySinglton*?p_my_singlton?=?MySinglton::instance();
72?????p_my_singlton->print();
73?????return?0;
74?}
75?/*result
76?construct?singlton
77?construct?my?singlton
78?haha
79?destruct?singlton
80?*/ OPMESH的singlton模版類的實現,這個似乎更專業些:)??1?//SingltonT.hh
??2?//=============================================================================
??3?//
??4?//??Implements?a?simple?singleton?template
??5?//
??6?//=============================================================================
??7?
??8?
??9?#ifndef?__SINGLETON_HH__
?10?#define?__SINGLETON_HH__
?11?
?12?
?13?//===?INCLUDES?================================================================
?14?
?15?//?OpenMesh
?16?#include?<OpenMesh/Core/System/config.h>
?17?
?18?//?STL
?19?#include?<stdexcept>
?20?#include?<iostream>
?21?
?22?
?23?//==?NAMESPACES?===============================================================
?24?
?25?
?26?namespace?OpenMesh?{
?27?
?28?
?29?//===?IMPLEMENTATION?==========================================================
?30?
?31?
?32?/**?A?simple?singleton?template.
?33?????Encapsulates?an?arbitrary?class?and?enforces?its?uniqueness.
?34?*/
?35?
?36?template?<typename?T>
?37?class?SingletonT
?38?{
?39?public:
?40?
?41???/**?Singleton?access?function.
?42???????Use?this?function?to?obtain?a?reference?to?the?instance?of?the?
?43???????encapsulated?class.?Note?that?this?instance?is?unique?and?created
?44???????on?the?first?call?to?Instance().
?45???*/
?46?
?47???static?T&?Instance()
?48???{
?49?????if?(!pInstance__)
?50?????{
?51???????//?check?if?singleton?alive
?52???????if?(destroyed__)
?53???????{
?54?????OnDeadReference();
?55???????}
?56???????//?first?time?request?->?initialize
?57???????else
?58???????{
?59?????Create();
?60???????}
?61?????}
?62?????return?*pInstance__;
?63???}
?64?
?65?
?66?private:
?67?
?68???//?Disable?constructors/assignment?to?enforce?uniqueness
?69???SingletonT();
?70???SingletonT(const?SingletonT&);
?71???SingletonT&?operator=(const?SingletonT&);
?72?
?73???//?Create?a?new?singleton?and?store?its?pointer
?74???static?void?Create()
?75???{
?76?????static?T?theInstance;
?77?????pInstance__?=?&theInstance;
?78???}
?79???
?80???//?Will?be?called?if?instance?is?accessed?after?its?lifetime?has?expired
?81???static?void?OnDeadReference()
?82???{
?83?????throw?std::runtime_error("[Singelton?error]?-?Dead?reference?detected!\n");
?84???}
?85?
?86???virtual?~SingletonT()
?87???{
?88?????pInstance__?=?0;
?89?????destroyed__?=?true;
?90???}
?91???
?92???static?T*?????pInstance__;
?93???static?bool???destroyed__;
?94?};
?95?
?96?
?97?
?98?//=============================================================================
?99?}?//?namespace?OpenMesh
100?//=============================================================================
101?#if?defined(OM_INCLUDE_TEMPLATES)?&&?!defined(OPENMESH_SINGLETON_C)
102?#??define?OPENMESH_SINGLETON_TEMPLATES
103?#??include?"SingletonT.cc"
104?#endif
105?//=============================================================================
106?#endif?//?__SINGLETON_HH__
107?//=============================================================================
108?
109?
110?//SingltonT.cc
111?//=============================================================================
112?//
113?//??Implements?a?simple?singleton?template
114?//
115?//=============================================================================
116?
117?
118?#define?OPENMESH_SINGLETON_C
119?
120?
121?//==?INCLUDES?=================================================================
122?
123?
124?//?header
125?#include?<OpenMesh/Core/Utils/SingletonT.hh>
126?
127?
128?//==?NAMESPACES?===============================================================
129?
130?
131?namespace?OpenMesh?{
132?
133?
134?//==?SINGLETON'S?DATA?=========================================================
135?
136?
137?template?<class?T>?
138?T*?SingletonT<T>::pInstance__?=?0;
139?
140?template?<class?T>
141?bool?SingletonT<T>::destroyed__?=?false;
142?
143?
144?//=============================================================================
145?}?//?namespace?OpenMesh
146?//=============================================================================
147?使用的時候如typedef SingletonT<LoopSchemeMaskDouble> LoopSchemeMaskDoubleSingleton;
- singlton in python
????? 那么在python中,作者提到的singlton的概念得到了放寬,
?????????? Alex Martelli makes the observation that what we really want with a
?????????? Singleton is to have a single set of state data for all objects. That is, you
?????????? could create as many objects as you want and as long as they all refer to
?????????? the same state information then you achieve the effect of Singleton.
????? 你可以有任意多的對象,但是它們都指向相同的狀態信息,即為singlton。Borg利用__dict__屬性巧妙的實現了一個
????? singlton 模式。
?1?class?Borg():?2?????shared_dict?=?{}
?3?????def?__init__(self):
?4?????????self.__dict__?=?self.shared_dict??
?5?
?6?class?Singleton(Borg):
?7?????def?__init__(self,?arg):
?8?????????Borg.__init__(self)
?9?????????self.val?=?arg
10?????def?__str__(self):?
11?????????print(self.__dict__)
12?????????return?self.val
13?
14?
15?if?__name__?==?'__main__':
16?????x?=?Singleton('abc')
17?????y?=?Singleton('def')
18?????print(x)
19?????print(y)
20?
21?output?=?'''
22?{'val':?'def'}
23?def
24?{'val':?'def'}
25?def
26?'''
這種方案,簡潔清楚,并且很容易通過繼承而復用。當然作者還提到許多其它的實現方法,對比下面的方法。
??1?class?OnlyOne:
?2??3?????class?__OnlyOne:
?4?????????def?__init__(self,?arg):
?5?????????????self.val?=?arg
?6?????????def?__str__(self):
?7?????????????return?'self'?+?self.val
?8?????????????#return?`self`?+?self.val
?9?????instance?=?None
10?????def?__init__(self,?arg):
11?????????if?not?OnlyOne.instance:
12?????????????OnlyOne.instance?=?OnlyOne.__OnlyOne(arg)
13?????????else:
14?????????????OnlyOne.instance.val?=?arg
15?????def?__getattr__(self,?name):
16?????????return?getattr(self.instance,?name)
17?
18?
19?x?=?OnlyOne('sausage')
20?print(x)
21?y?=?OnlyOne('eggs')
22?print(y)
23?z?=?OnlyOne('spam')
24?print(z)
25?
26?print(x)
27?print(y)
28?print(z)
29?print('x')
30?print('y')?
31?print('z')?
32?
33?print(x.instance)
34?output?=?'''
35?selfsausage
36?selfeggs
37?selfspam
38?selfspam
39?selfspam
40?selfspam
41?x
42?y
43?z
44?selfspam
45?''' 與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的<读书笔记> Thinking in python (Python 设计模式) 1. Singlton的c++与python的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 节奏型是什么意思(节奏型)
- 下一篇: 天正字体放在哪个文件夹里(天正字体放在哪