C++中,static成员变量和所有non-localstatic变量一样,在进入main函数之前创建。我们考虑如下代码:
<span style="font-size:18px;">#include <iostream>
using namespace std;
class Bowl
{
public:
Bowl(int marker)
{
cout << "Bowl(" << marker << ")" << endl;
}
void f1(int marker)
{
cout << "f1(" << marker << ")" << endl;
}
};
class Table
{
public:
static Bowl bowl1;
Table()
{
cout << "Table()" << endl;
bowl2.f1(1);
}
void f2(int marker)
{
cout << "f2(" << marker << ")" << endl;
}
static Bowl bowl2;
};
Bowl Table::bowl1(1);
Bowl Table::bowl2(2);
class Cupboard
{
public:
Bowl bowl3;
static Bowl bowl4;
Cupboard(): bowl3(3)
{
cout << "Cupboard()" << endl;;
bowl4.f1(2);
}
void f3(int marker)
{
cout << "f3(" << marker << ")" << endl;
}
static Bowl bowl5;
};
Bowl Cupboard::bowl4(4);
Bowl Cupboard::bowl5(5);
int main(void)
{
cout << "Creating new Cupboard() in main" << endl;
Cupboard *cup = new Cupboard();
cout << "Creating new Cupboard() in main" << endl;
cup = new Cupboard();
}
</span>
Bowl(1)
Bowl(2)
Bowl(4)
Bowl(5) //在main函数进入之前创建的四个staticBowl对象
Creating new Cupboard() in main//第一次构造函数
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
而java中的static成员变量则是在(1)该成员变量所在的类创建一个对象时(2)访问该成员变量所在的类的static成员函数或者static成员变量时创建。考虑以下代码。
<span style="font-size:18px;">class Bowl
{
Bowl(int marker)
{
System.out.println("Bowl(" + marker + ")");
}
void f1(int marker)
{
System.out.println("f1(" + marker + ")");
}
}
class Table
{
static Bowl bowl1 = new Bowl(1);
Table()
{
System.out.println("Table()");
bowl2.f1(1);
}
void f2(int marker)
{
System.out.println("f2(" + marker + ")");
}
static Bowl bowl2 = new Bowl(2);
}
class Cupboard
{
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
Cupboard()
{
System.out.println("Cupboard()");
bowl4.f1(2);
}
static void f3(int marker)
{
System.out.println("f3(" + marker + ")");
}
static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialization
{
public static void main(String[] args)
{
Cupboard.f3(0);
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
new Cupboard();
}
}
</span>
Bowl(4)
Bowl(5)
f3(0)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
解读:
Bowl(4)
Bowl(5)
f3(0)
在调用Cupboard.f3(0)时,为了调用该static成员函数必须创建Cupboard类里面的所有static对象。注意在这里仅仅创建了Cupboard类的两个static对象,没有创建non-static的bowl3对象,也没有调用Cupboard类的构造函数,因为在这里我们没有创建Cupboard类的实例。
Cupboard类的构造函数在下面new的时候调用。在这时由于该类中的static成员变量bowl4和bowl5已经创建完毕,故不再创建。
若将main函数改为
<span style="font-size:18px;">public static void main(String[] args)
{
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
new Cupboard();
}
</span>
则输出变为:
Creating new Cupboard() in main
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
在这里我们第一次创建Cupboard类的对象时之前并没有创建过类中的static成员变量,因此bowl4和bowl5会在第一次创建Cupboard对象时创建。注意尽管bowl3定义在bowl4和bowl5之前,创建时依然按照4->5->的顺序。因为static变量会在non-static变量之前创建。