全局变量的缺陷:
- 变量名冲突:项目经理必须小心地维护变量名规则,所有工程师开发代码时,没遇到一个全局变量,都必须仔细分辨该变量究竟属于哪个模块,哪个程序
- 耦合度难题:全局变量实际上大大增加了函数和模块之间的耦合度
- 单个实例问题:全局变量不能阻止程序员定义一个类的多个对象实例,如果没有其他技术手段的帮助,保证一个类只有个类只有单个实例很困难
- 初始化顺序:全局变量不可能保证相互之间遵循特定的初始化顺序,完全由编译器决定。对于简单变量来说,没什么麻烦,但是对于类的对象实例,构造函数被调用的顺序有时显得非常重要
- 多线程访问:当多个并发的线程都需要访问某些全局变量时,必须使用各种同步机制,小心地保护这些全局变量,以免陷入并发冲突的泥潭
单件模式:
设计意图:保证一个类只有一个对象实例,并且提供一个访问该对象实例的全局访问点(不允许程序员随意创建该类的对象实例,但是可以从该类提供的静态成员函数得到该类唯一的对象实例的指针或者引用)
基本结构:
在单件模式的结构图中,只有一个类,即单件类,定义了一个静态方法,客户程序可以通过这个方法获取该类的唯一的对象实例
实现:
c++实现注意点:静态成员函数只能访问静态成员变量(因为静态成员函数调用时,编译器不会吧实例对象的指针作为参数传递给静态成员函数);因为编译器不会在每一个实例中分配静态数据成员,所以必须按照定义全局变量的方式在类声明代码之外显示地定义它们
使用单件类最易犯的错误就是把全局变量收集起来放进一个单件类中,这种做法对系统的架构没有任何好处
FishiGUI中的单件类:
为了将该类的对象实例数限制为一个,必须禁止用户直接创建该类的实例,把构造函数的访问权限设为protected(如果不用于被继承可以设置为private),然后通过全局访问点-------GetScreen()方法来访问FG_Screen
单件模式的内存释放:对一个程序来说,如果某些内存的分配数量有一个最大值,程序运行中所分配的内存数量总不会超过该最大值,这些内存就可以被视为“内存池”,不是放内存池的空间,并不会对整个系统造成伤害,因为他不会应为无限增长而耗尽系统内存;如果程序运行中,没有动态分配的内存空间会无限增长,就算客户代码非常小心,也无法避免内存耗尽,这些内存就被称为内存泄漏
如果单件类的对象实例有且只有一个,并且它占据的内存数量是恒定得,不在增长的,即便不释放该对象实例的内存空间,对程序不会造成任何威胁;但是如果单件类的构造函数除了分配内存以外,还要分配某些系统资源,而这些资源不会随着进程的结束而自动释放,那么在不进行完全清理的前提下,程序的反复运行就有可能造成系统资源的耗尽或后续访问时的冲突,这时就需要在单件类的西沟函数中逐一执行资源的释放操作