本篇文章会深入的讲解在类对象创建的时候,构造函数、析构函数的调用顺序以及普通成员变量和静态成员变量的创建顺序。
* 析构函数的调用顺序与构造函数正好相反。
1、先看如下代码,注意:构造函数和析构函数一定是要public,因为系统是要自动去调用的,不然编译会出错。
* 类B继承于类A
class A
{
public:
A()
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
class B : public A
{
public:
B()
{
cout << "B()" << endl;
}
~B()
{
cout << "~B()" << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
B b;
return 0;
}
解析:对于单继承的时候,对于构造方法的调用是先调用父类再调用子类,而对于析构方法是先调用子类再调用父类,结果如下:
A()
B()
~B()
~A()
2、多继承的时候
* C继承B、A
class A
{
public:
A()
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
class B
{
public:
B()
{
cout << "B()" << endl;
}
~B()
{
cout << "~B()" << endl;
}
};
class C : public B, public A
{
public:
C()
{
cout << "C()" << endl;
}
~C()
{
cout << "~C()" << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
C c;
return 0;
}
class C : public B, public A
所以构造函数:先B再A,析构:先A再B
结果如下:
B()
A()
C()
~C()
~A()
~B()
3、当成员变量是类的时候
using namespace std;
class A
{
public:
A()
{
cout << "A()" << endl;
}
A(int x)
{
cout << "A(" << x << ")" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
class B : public A
{
public:
B():a1(1),a2(2)
{
cout << "B()" << endl;
}
~B()
{
cout << "~B()" << endl;
}
private:
A a2;
A a1;
};
int _tmain(int argc, _TCHAR* argv[])
{
B b;
return 0;
}
分析:类B中含有两个类A的对象a2、a1,当b对象被创建的时候,先去创建类A中的资源,再来创建类B中的资源。所以此列先调用了类A的构造函数,因为类A中没有其他成员变量了,所以接下来创建类B的资源,所以先将类B中的所有变量创建好,即如果是类对象就会去调用相应的构造函数,最后再去调用类B的构造函数。
结果如下:
A()A(2)
A(1)
B()
~B()
~A()
~A()
~A()
接下来是一个列子,如果看懂了的话,就表示前面的调用关系你都清楚了:
class A
{
public:
A()
{
cout << "A()" << endl;
}
A(int x)
{
cout << "A(" << x << ")" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
class B : public A
{
public:
B():a2(2),a1(1)
{
cout << "B()" << endl;
}
B(int x)
{
cout << "B(" << x << ")" << endl;
}
~B()
{
cout << "~B()" << endl;
}
private:
A a2;
A a1;
};
class C
{
public:
C()
{
cout << "C()" << endl;
}
C(int x)
{
cout << "C(" << x << ")" << endl;
}
~C()
{
cout << "~C()" << endl;
}
};
class D : public C, public B
{
public:
D():b(3)
{
cout << "D()" << endl;
}
D(int x)
{
cout << "D(" << x << ")" << endl;
}
~D()
{
cout << "~D()" << endl;
}
private:
B b;
};
int _tmain(int argc, _TCHAR* argv[])
{
D d;
return 0;
}
分析:你可以画一颗继承树,然后把相应节点上的类所需要的成员变量写到傍边,然后利用中序遍历去遍历这颗树,每个节点按以上的规则(先成员变量(先定义先创建),再构造函数)---个人见解,仅供参考。
结果如下:
C()
A()
A(2)
A(1)
B()
A()
A()
A()
B(3)
D()
~D()
~B()
~A()
~A()
~A()
~B()
~A()
~A()
~A()
~C()
下面是关于静态成员变量的初始化及其顺序。
class A
{
public:
A()
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
}
public:
static A a;
};
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
结果:无
class A
{
public:
A()
{
cout << "A()" << endl;
}
A(int x)
{
cout << "A(" << x << ")" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
class B : public A
{
public:
B()
{
cout << "B()" << endl;
}
B(int x)
{
cout << "B(" << x << ")" << endl;
}
~B()
{
cout << "~B()" << endl;
}
public:
static A a;
};
static B::A a(1);
int _tmain(int argc, _TCHAR* argv[])
{
B b;
return 0;
}
结果:
A(1)
A()
B()
~B()
~A()
~A()
分析:通过前面两段代码和结果,可以看出当静态成员变量调用语句static B::A a; 初始化时它就不会被初始化,而一旦有这条语句就会在编译的时候就初始化了。
现在可以讲以上的知识连在一起了。
class A
{
public:
A()
{
cout << "A()" << endl;
}
A(int x)
{
cout << "A(" << x << ")" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
class B : public A
{
public:
B():a2(2),a1(1)
{
cout << "B()" << endl;
}
B(int x)
{
cout << "B(" << x << ")" << endl;
}
~B()
{
cout << "~B()" << endl;
}
private:
A a2;
A a1;
public:
static A a3;
};
class C
{
public:
C()
{
cout << "C()" << endl;
}
C(int x)
{
cout << "C(" << x << ")" << endl;
}
~C()
{
cout << "~C()" << endl;
}
};
class D : public C, public B
{
public:
D():b(3)
{
cout << "D()" << endl;
}
D(int x)
{
cout << "D(" << x << ")" << endl;
}
~D()
{
cout << "~D()" << endl;
}
private:
B b;
public:
static A a;
static A aa;
};
A D::aa(1);
A D::a(2);
A B::a3(3);
int _tmain(int argc, _TCHAR* argv[])
{
D d;
return 0;
}
结果如下:
A(3)
C()
A()
A(2)
A(1)
B()
A()
A()
A()
B(3)
D()
~D()
~B()
~A()
~A()
~A()
~B()
~A()
~A()
~A()
~C()
~A()
~A()
~A()
* 记住静态变量的初始化也是按初始化语句的先后顺序进行的。
虽然上面的知识深入没有什么意识,不过了解一点总好,平时不注意,笔试的时候就坑了。