还是关于C++对象模型,前一篇读书笔记中涉及到了静态成员变量的问题,后来发现需要思考的东西还是有很多的,下面便一一道来。
首先,类中的static member在计算类的大小时并不计算在内,举例如下,原因是什么呢?
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class X{ public: int data; static int num; }; sizeof(X) = 4;
大部分人应该知道,static member相当于是全局变量,而全局变量是存储在静态区里的,所以和类或者对象是相分离的,因此在计算sizeof(X)时就不会计算在内。既然是static member是全局变量,那么不管程序中产生多少objects,static member永远只存在一份实例,甚至即使该类没有任何实例,其static member也可以已经存在。
第二,要访问类的静态成员,光声明是不够的,上面的class X中只是对num的声明,如果你直接在其他函数中实例化一个对象,并用这个对象访问static member num,那么编译器会给你来上一句类似“fatal error LNK1120: 1 个无法解析的外部命令”的话。为什么呢?因为类里面的static int num只是一句声明而并非定义!如果要访问一个变量,则它必须要被定义过才行!而定义则必须在类的外部(也不能是其他函数内部,跟定义全局变量一样)。这里可以直接在class X的外部直接定义:int X::num = 10; 定义以后就可以直接访问了。
说到了静态成员变量的使用就不由自主的联想到单例模式的实现,下面也就简单介绍下单例模式。
单例模式(Singleton)可能是应用最为广泛的设计模式,目的是保证对于某个类,只能实例化一个这种类的对象,并提供一个访问它的全局访问点。很多情形下可以比对单例模式,比如一个系统中只应该有一个文件系统和一个窗口管理器,某个程序只允许产生一个交互窗口等等。一个常用的实现方法是将创建这个唯一实例的操作隐藏在一个类操作之中,由它保证只有一个实例被创建。这个操作可以访问保存唯一实例的变量,而且保证在未创建实例时,创建实例。下面给出一种实现:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class Singleton{ 2 public: 3 static Singleton* GetInstance(); 4 int getVar(); 5 void setVar(int); 6 virtual ~Singleton(); 7 private: 8 static Singleton* m_instance; 9 int var; 10 protected: 11 Singleton(); 12 }; 13 14 Singleton *Singleton::m_instance=0; 15 16 Singleton::Singleton() 17 { 18 this->var = 100; 19 cout<<"Singleton constructor."<<endl; 20 } 21 22 Singleton::~Singleton() 23 { 24 cout<<"Singleton Destructor."<<endl; 25 } 26 27 Singleton* Singleton::GetInstance() 28 { 29 if(m_instance==NULL) 30 m_instance = new Singleton(); 31 return m_instance; 32 } 33 34 int Singleton::getVar() 35 { 36 return this->var; 37 } 38 39 void Singleton::setVar(int var) 40 { 41 this->var = var; 42 }
可以自己在main函数里测试getVar()和setVar()的操作,看是否操作的是同一个实例。