static限定
(1)定义函数内部的静态变量,改变变量的存储期。
在函数内部定义一个static对象,该对象的作用域局限在该函数体内,但是对象将被
存储于静态数据区中,而不是在栈内。这个对象只在函数第一次调用时初始化一次,以后
它将在多次函数调用之间保持它的值。
对于用户自定义类型的静态对象,使用规则与一般的静态变量相同,它同样也必须有
初始化操作,程序控制第一次到达对象的定义点时,而且仅在第一次,需要执行构造函数
初始化,当程序从main()中退出时,将调用析构函数实施对象的销毁。
(2)限定名字的可见性。
在源文件中声明为static的对象或函数名字仅对当前编译单元可见。这些名字是内部链接
的。可以在其他的编译单元中使用同样的名字,而不会发生冲突。
int a = 0; //a为全局可见
extern int a = 0; //效果同上
static int a = 0; //a为编译单元链接,仅对当前编译单元可见
(3)限定数据成员
静态数据成员被当作该类类型的全局变量。对非静态数据成员,每个对象都有自己的拷贝,
而静态数据成员对整个类类型只有一个,由这个类型的所有对象共享访问。与全局变量相比,
静态数据成员有两个优点:
#1.静态数据成员没有进入成员的全局作用域,只有在类作用域中,不会与全局域中的
其他名字产生冲突。
#2.可以实现信息隐藏,静态成员可以是private成员,而全局变量不能。在类的数据成员
声明前加关键字static,就使该数据成员成为静态的。static成员仍然遵循访问控制规则。
class ClassA
{
private:
static int m_Count; //类中声明
public:
ClassA(){ m_Count++; }
virtual ~ClassA(){ m_Count--; }
int getCount() const { return m_Count; }
};
类中的m_Count数据成员由每个Object对象共享,因为对每个对象而言,当前程序中的对象数目
都是相同的。可是这里的count数据成员在何时初始化呢?
static 数据成员在类定义之外初始化。在定义时要使用类名字限定修饰。下面是count的初始化:
int ClassA::m_Count = 0; //在类外定义初始化
static 成员只能定义一次,所以定义一般不放在头文件中,而是放在包含函数定义的源文件中。
静态数据成员可以是任何类型,甚至是所属类类型。也可以用static const定义类中的常量。
和static成员一样,static const数据成员的初始化也是在类外。但是标准C++允许在类定义里
初始化整值类型的static const,但其他类型不能在类中初始化。例如:
class Account
{
static const int m_NameSize = 16; //OK
static const char m_Name[m_NameSize] = "Saving Account" //Error
......
};
(4)限定成员函数
静态成员函数的声明是在类定义中的函数声明前加static关键字,在类外定义静态成员函数时不需要
加关键字static。
静态成员函数可以用成员访问语法调用,也可以直接用类名限定静态成员函数名调用。
例如:
class Object
{
static int m_Count;
public:
Object(){ m_Count++; }
virtual~Object(){ m_Count--; }
static int getCount(){ return m_Count; }
};
......
Object obj;
obj.getCount();
obj::getCount();
静态成员函数没有this指针,在静态成员函数中显示或隐式地引用this指针都会引起编译错误。因此,
静态成员函数中不能访问非静态数据成员,也不能调用非静态成员函数。静态成员函数也不能声明
为const或volatile,因为cv限定词是限定this指针的。
非静态数据成员和成员函数分别是对象的属性和操作。静态数据成员则是类的属性,而静态成员
函数就是类的操作。
总之,关于静态成员函数遵循以下规则:
#1.被类的所有对象所共享,在对象产生以前便分配好了内存空间
#2.静态成员函数不能被const或volatile所限定
#3.静态成员函数不能访问非静态数据成员,也不能调用非静态成员函数
#4.静态成员函数在可访问情况下可以直接以类名限定形式调用,也
可以直接用对象所调用,当然,也可以用类成员函数直接调用。