注意:

C++静态成员变量是用static修饰的成员变量,不属于对象的一部分,而是类一部分,因此可以在没有实例化任何对象的时候使用静态成员变量。但是必须初始化它

之所以必须初始化它是因为:全局静态变量自动初始化,但是局部变量


由于静态变量只能被初始化一次,所以初始化成员变量不要放在如下地方:1.类的构造函数(构造函数可能多次被调用);2.头文件中(头文件可能被包含入多个地方,也可能被执行多次)。应该放在应用程序中,类以外的任何地方初始化,例如:在main中,或全局函数中,或任何函数之外:


所有的对象(不仅仅是静态对象)初始化都只有一次
因为a初始化为1之后,一直都没有销毁(因为是static),所以不会再次初始化


内存分配方式有三种:  
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。  
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。  
(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

类的静态成员变量和函数中的静态变量一样,在编译的时候就分配内存了,直到程序退出才释放,并不是随着对象的删除而释放的:

类的静态成员变量为什么必须得在类外初始化?


我的理解: 由于静态变量在编译期间必须初始化,全局变量的静态或者非静态的变量都可以赋初值0。而类中的变量要用构造函数来初始化,但是在编译期间没有创造对象,所以就没有运行构造方法。故在编译期间没有给类的静态变量初始化。所以要在类外 main之前要给该静态变量初始化,不管该静态变量的作用域为private还是public,因为编译期间private没有影响。但是一旦进入运行时,就不可以调用类中的private变量。



调用的时候可以通过对象调用,也可以通过类直接调用

class A
{
public:
int i;    //有默认值
};
class B
{
public:
static int n;
static A Aobj;
};
int B::n = 1;    //静态成员变量的初始化
A B::Aobj;       //静态成员变量的初始化(实例化)
void main()
{
   B Bobj;
   printf("B::n=%d Bobj.n=%d Bobj.Aobj.i=%d/n", B::n, Bobj.n, Bobj.Aobj.i);
}

私有的静态成员变量也是放在类外初始化的.这看起来跟它的私有属性不相符.

再做下面的测试,发现了一个有趣的现象.

class B
{
staticint i;
public:
   B(){i=3;};    //把这行注释掉,输出变成2
int p(){return i;};
};
int B::i = 2;      //把这行注释掉,编译报错
void main()
{
   B Bobj;
   printf("private: static int B::i=%d/n", Bobj.p());    //输出3
}

1、“这样看来.类外的初始化那一行根本没有起到初始化的作用.它赋的值根本没用.(对私有静态成员变量是这样.公有的还是有作用的)“  这句话是不对的!!!

因为 对于static成员变量是否是private数据并没有影响,因为设定static成员变量初值时,不受任何存取权限的束缚,

而静态变量赋值是在编译阶段,所以早于构造函数,当类声明对象时 i=3覆盖了前面的值。所以才是 3

2、当把B(){i=3;};注掉时,没有了构造函数里的赋值覆盖,所以结果是2 ,亲测

3、因为由于静态变量只能被初始化一次,所以放在函数体外或全局函数中


不过要注意的是,static成员变量的类型要出现在初始化语句中,因为这是初始化操作,不是赋值操作。static成员变量是在初始化(而不是在类声明时候)才定义出来的。如果没有初始化操作,会产生链接错误