第一个例子:
#include <iostream>
using namespace std;
class A
{
public:
int i;
A() { cout << "AAa" << endl; }
~A() { cout << "qqqq" << endl; }
protected:
private:
};
class B :public A
{
public:
B(int a) { cout << "BBB" << endl; }
~B() { cout << "wwwww" << endl; }
};
int main111()
{
B b(3);
return 0;
system("PAUSE");
}
打印结果:总是先调用被继承的基类的构造函数,然后再调用自己的构造函数,析构函数相反,先调用自身的的析构函数,再调用基类的析构函数。
第二个例子:
#include <iostream>
using namespace std;
class A {
public:
A() { cout << "A"; }
~A() { cout << "~A"; }
};
class B {
public:
B() { cout << "B"; }
~B() { cout << "~B"; }
private:
A a;
};
class C : public A {
public:
C() { cout << "C"; }
~C() { cout << "~C"; }
private:
B b;
A a;
};
int main()
{
cout << "=======================================\n";
cout << "A类对象的构造过程: ";
A a;
cout << "\n======================================\n\n";
cout << "B类对象的构造过程: ";
B b;
cout << "\n=======================================\n\n";
cout << "C类对象的构造过程: ";
C *p = new C();
// 动态申请的内存别忘了释放,否则不会调用析构函数,任何时候delete 空指针也不会错
delete p;
// 注意,如果这里没有刷新缓冲区的话最后的那三个析构函数被执行,但数据留在缓冲区中,没有输出
// 因为析构函数里面也没有cout<<endl;之类的刷新缓冲区,没有刷新缓冲区的的输出结果如图二
cout << "\n=======================================\n";
return 0;
}
打印结果:对象初始化时候,先对类成员变量分配空间和和初始化,然后调用构造函数(和public、private无关),对象析构时相反所以这里对于创建a对象直接调用A的构造函数,创建b对象的时候先对成员B类的成员变量进行初始化输出A,然后调用B类的构造函数输出B,创建c对象先调用父类A的构造函数输出A,接着初始化C自身类的成员变量b、a,分别输出AB、A,最后调用C自身的构造函数输出C,析构函数相反。所以从这里可以总结出的调用顺序是:先调用父类的构造函数,接着调用类成员对象的构造函数(因为先初始化成员),最后才轮到调用自身的构造函数。