title: 关于类成员变量初始化顺序 author: Harry Chen key: the-initialization-order-of-class-member-variables layout: article —-
java和C#语言里类变量初始化的顺序是
- 类成员变量初始化先于类的构造函数
- 静态成员变量先于实例变量
- 父类成员变量先于子类成员变量 C#相反
- 父类构造函数先于子类构造函数
举一个java的例子:
:::java
class Base
{
public static Test a=new Test("a");
public static Test b;
public Test c=new Test("c");
public Test d;
static
{
b=new Test("b");
}
public Base()
{
d=new Test("d");
}
public static void main(String[] args) {
new Derived();
}
}
class Derived extends Base
{
public static Test da=new Test("da");
public static Test db;
public Test dc=new Test("dc");
public Test dd;
static
{
db=new Test("db");
}
public Derived()
{
dd=new Test("dd");
}
}
class Test
{
public Test (String name) {
System.out.println(name);
}
}
运行结果是:
a
b
da
db
c
d
dc
dd
C++中没有成员变量定义时初始化的方式,所以有如下几条:
-
构造函数初始化列表的变量优先于构造函数(至少明显的写在前面)
-
静态成员变量先于实例变量
-
父类成员变量先于子类成员变量
-
父类构造函数先于子类构造函数
举一个例子:
:::cpp
#include <iostream>
#include <string>
using namespace std;
class Test
{
public:
Test(string n)
{
cout<<n<<endl;
}
};
class Base
{
public:
static Test* a;
Test* b;
Test* c;
Base():b(new Test("b"))
{
c=new Test("c");
}
virtual ~Base()
{
if(a) delete a;//似乎是很欠妥的做法
if(b) delete b;
if(c) delete c;
}
};
Test* Base::a=new Test("a");
class Derived:Base
{
public:
static Test* da;
Test* db;
Test* dc;
Derived():db(new Test("db"))
{
dc=new Test("dc");
}
~Derived()
{
if(da) delete da;//似乎是很欠妥的做法
if(db) delete db;
if(dc) delete dc;
}
};
Test* Derived::da=new Test("da");
void main()
{
Derived d;
}
结果是:
a
da
b
c
db
dc
另外需要注意一点:析构函数是先子类再父类的,而且虚析构函数也是面试笔试经常考的问题。
PREVIOUS关于const和指针的专题
NEXTC++变量的初始化方式