一、面向过程中的static
按存储区域分,全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域,局部变量存放在内存的栈区。
1定义全局静态变量的好处:
<1>不会被其他文件所访问,修改
<2>其他文件中可以使用相同名字的变量,不会发生冲突。
2在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。
(1)和全局静态变量一样都在静态存储区域
(2)初始化:未经初始化的全局静态变量和局部静态会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化)
注:当static用来修饰局部变量的时候,它就改变了局部变量的存储位置,从原来的栈中存放改为静态存储区。但是局部静态变量在离开作用域之后,并没有被销毁,而是仍然驻留在内存当中,直到程序结束,只不过我们不能再对他进行访问。
3 静态函数
在函数的返回类型前加上关键字static,函数就被定义成为静态函数。
函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其
存储说明符auto,register,extern,static,对应两种存储期:自动存储期和静态存储期。
auto和register对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。
关键字extern和static用来说明具有静态存储期的变量和函数。用static声明的局部变量具有静态存储持续期(static storage duration),或静态范围(static extent)。虽然他的值在函数调用之间保持有效,但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化。(摘自《C++ Primer》 P337)
关键字extern和static用来说明具有静态存储期的变量和函数。用static声明的局部变量具有静态存储持续期(static storage duration),或静态范围(static extent)。虽然他的值在函数调用之间保持有效,但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化。(摘自《C++ Primer》 P337)
二 面向对象程序设计中的static
1. 静态数据成员
1) 内存中的位置:静态存储区
2) 初始化和定义:
<1> 静态数据成员定义时要分配空间,所以不能在类声明中定义。
<2> 静态数据成员在程序中只能提供一个定义,所以静态数据成员的初始化不能在类的头文
3) 访问:
<1> 类对象名.静态数据成员
<2> 类类型名::静态数据成员
4) 说明:
a.static数据成员和普通数据成员一样遵public, protected, private 访问规则。
b.对于非静态数据成员,每个类对象都有自己的拷贝。静态数据成员被当作类的全局对象,
5) 同全局对象相比,使用静态数据成员有两个优势:
<1> 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的
<2> 可以实现信息隐藏。静态成员可以是private成员,而全局对象不能。
6) 应用:
class Account {
Account( double amount, const string &owner );
String owner() { return _owner ;}
private:
static double _interestRate;
double _amount;
string _owner;
};
为什把_interestRate声明为static,而_amount和_owner不呢?
这是因为每个Account对应不同的主人,有不同数目的钱,而所有Account的利率却是相同的。
这是因为每个Account对应不同的主人,有不同数目的钱,而所有Account的利率却是相同的。
因为在整个程序中只有一个_interestRate数据成员,他被所有Account对象共享,所以把
_interestRate值可能变化,所以不能声明为const。因为_interestRate是静态的,所以它只需要
7)静态数据成员的“唯一性”本质(独立于类的任何对象而存在的唯一实例),使他能够以独特
<1> 静态数据成员的类型可以是其所属类,而非static数据成员只能被声明为该类对象的指针
class Bar{
public:
//...
private:
static Bar mem1; //OK
Bar *mem2; //OK
Bar mem3; //错误
};
public:
//...
private:
static Bar mem1; //OK
Bar *mem2; //OK
Bar mem3; //错误
};
<2> 静态数据成员可以被作为类成员函数的缺省实参,而非static数据成员不可以。例如:
extern int var;
class Foo {
private:
int var;
static int stcvar;
public:
//错误:被解析为非static的Foo:var
//没有相关的类对象
int mem1( int = var );
private:
int var;
static int stcvar;
public:
//错误:被解析为非static的Foo:var
//没有相关的类对象
int mem1( int = var );
//OK:解析为static的Foo:stcvar
//无需相关的类对象
int mem2( int = stcvar );
//无需相关的类对象
int mem2( int = stcvar );
//OK:int var 的全局实例
int mem3( int = ::var );
};
int mem3( int = ::var );
};
8) 类模板的静态数据成员以后讨论^-^
2. 静态成员函数
1) 声明:在类的成员函数返回值之前加上关键字static,他就被声明为一个静态成员函数。静
2) 定义:出现在类体外的函数定义不能指定关键字static。
3) 作用:主要用于对静态数据成员的操作
4) 静态成员函数与类相联系,不与类的对象相联系。
5) 静态成员函数不能访问斐静态数据成员。因为非静态数据成员属于特定的类实例。
6) 静态成员函数没有this指针,因此在静态成员函数中隐式或显示的引用这个指针都将导致编
7) 访问:可以用成员访问操作符(.)和箭头(->)为一个类对象或指向类对象的指针调用静态成员