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 '''

<读书笔记> Thinking in python (Python 设计模式) 1. Singlton的c++与python的实现相关推荐

  1. 【读书笔记】单人FPS关卡设计模式

    读了加利福尼亚大学的Kenneth Hullett, Jim Whitehead所写的"Design Patterns in FPS Levels"对其中的要点做下笔记,方便以后回 ...

  2. Java程序性能优化 读书笔记(十)并行设计模式:Future模式

    转载:Java多线程编程中Future模式的详解<转> 参考:葛一鸣,Java程序性能优化.清华大学出版社. 随着多核时代的到来,CPU的并行能力有了很大的提升.在这种背景下,传统的串行程 ...

  3. python权威指南 pdf_Ansible权威指南pdf txt mobi下载及读书笔记

    Ansible权威指南pdf txt mobi下载读书笔记 读书笔记:工作机制:基于openSSH通信,需安装SSH Python,底层基于SSH协议,windows基于PowerShell仅客户侧. ...

  4. 黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第十一章 攻击性取证

    黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第十一章 攻击性取证 文章目录 黑帽python第二版(Black Hat Python 2nd Edi ...

  5. 计算机毕业设计django基于python的读书笔记共享平台

    项目介绍  本论文主要论述了如何使用PYTHON语言开发一个读书笔记共享平台 ,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发.在引言中,作者将论述读书笔 ...

  6. 计算机毕业设计django基于python的读书笔记共享平台(源码+系统+mysql数据库+Lw文档)

    项目介绍 本论文主要论述了如何使用PYTHON语言开发一个读书笔记共享平台 ,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发.在引言中,作者将论述读书笔记 ...

  7. python你想知道的都在这里 python资源大全中文版

    Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-python 是 vinta 发起维护的 Python 资源列 ...

  8. 《Python学习手册》读书笔记

    原文地址为: <Python学习手册>读书笔记 之前为了编写一个svm分词的程序而简单学了下Python,觉得Python很好用,想深入并系统学习一下,了解一些机制,因此开始阅读<P ...

  9. 《Deep Learning With Python second edition》英文版读书笔记:第十一章DL for text: NLP、Transformer、Seq2Seq

    文章目录 第十一章:Deep learning for text 11.1 Natural language processing: The bird's eye view 11.2 Preparin ...

最新文章

  1. workerman连接mysql_workerman Mysql使用
  2. spring mvc学习(49):返回json数据
  3. 如何避免重要需求遗漏?
  4. Ubuntu系统下go语言环境的搭建
  5. 【物理应用】基于matlab非序贯蒙特卡洛法评估风电系统【含matlab源码 766期】
  6. Windows下MySQL的安装步骤(有图详解)
  7. “十三五”公共安全规划涉及哪些安防概念?
  8. 央企招聘:中储粮集团2023公开招聘公告(校招+社招,共700人)
  9. 蓝牙耳机什么牌子音质好听?蓝牙耳机音质排行榜
  10. 1. 学校在线考试系统
  11. Gensim介绍以及实践
  12. 盘点 2021 年十大网络安全事件
  13. 随身WiFi刷Debian系统折腾指南
  14. java人工智能之神经网络中的层数怎么确定
  15. 深度剖析淘宝天猫搜索逻辑
  16. 配置Tomcat详细教程!
  17. 问题集锦:SwitchResX自定义分辨率可能遇到的问题以及解决办法
  18. 修改win2003远程桌面端口3389端口
  19. 光纤位移传感器工作原理
  20. 14 MySQL-视图

热门文章

  1. VTK:相互作用之PickableOff
  2. OpenCV calcHist()创建直方图的实例(附完整代码)
  3. C++归并排序(附完整源码)
  4. C语言编译器有哪些?
  5. python所有软件都打不开机怎么办_电脑软件,小编教你电脑所有软件都打不开怎么解决...
  6. 家庭财务管理系统_我31岁,30天整理出这些财务笔记干货,从宝妈成功逆袭成为会计...
  7. php 内容转换dom,php – 防止DOMDocument :: loadHTML()转换实体
  8. php 开启imagick,PHP-Imagick:在Imagick项目上设置重力
  9. linux du -h按文件大小,【玩转linux命令】du党
  10. 46栈内存溢出、内存区域(程序计数器、Java 虚拟机栈、本地方法栈、Java 堆、方法区、直接内存、内存溢出)与内存溢出(对象实例化分析)