构造函数:
- 如果有基类,则按照继承的顺序调用基类构造函数
- 如果有成员类,则按照声明顺序调用成员类的构造函数
- 自己的构造函数
话不多说,看代码:
#include<iostream>
using namespace std;
class Data //作为下面的成员类
{
public:
Data(int x) :x(x)
{
cout << "Data cons. " << endl;
}
~Data() { cout << "Data des. " << endl; }
private:
int x;
};
class BaseA //第一个基类
{
public:
BaseA(int x) :dl(x) { cout << "BaseA cons. " << endl; }
~BaseA() { cout << "BaseA des" << endl; }
private:
Data dl; //成员类
};
class BaseB //第二个基类
{
public:
BaseB(int x) :dl(x) { cout << "BaseB cons. " << endl; }
~BaseB() { cout << "BaseB des" << endl; }
private:
Data dl; //成员类
};
class Derived :public BaseB,public BaseA //注意继承顺序
{
public:
Derived(int x) :BaseA(x),BaseB(x), d2(x) { cout << "Derived cons. " << endl; } //注意初始化顺序
~Derived() { cout << "Derived des. " << endl; }
private:
Data d2;
};
int main()
{
Derived obj(5);
return 0;
}
答案:
由此我们可以看到,基类有成员类,所以要先调用基类的成员类的构造函数,再调用基类的构造函数,按照继承顺序重复。然后子类也有成员类,所以先调用子类的成员类的构造函数,再调用自己的构造函数。
再来看看析构函数:
其实很简单!!! 就是构造函数反过来。但是有几点要注意。
- 一般情况下,类指针和引用在return时不会自动调用析构函数。
- delete指向子类对象的子类类型指针,按照规则进行。
- delete指向子类对象的基类类型指针时,如果基类的析构函数不是虚函数(virtual),那么只能够调用父类而不能调用子类的析构函数。
没有virtual时:
#include<iostream>
using namespace std;
class Data //作为下面的成员类
{
public:
Data(int x) :x(x)
{
cout << "Data cons. " << endl;
}
~Data() { cout << "Data des. " << endl; }
private:
int x;
};
class BaseA //第一个基类
{
public:
BaseA(int x) :dl(x) { cout << "BaseA cons. " << endl; }
~BaseA() { cout << "BaseA des" << endl; } //没有virtual
private:
Data dl; //成员类
};
class Derived :public BaseA
{
public:
Derived(int x) :BaseA(x), d2(x) { cout << "Derived cons. " << endl; } //注意初始化顺序
~Derived() { cout << "Derived des. " << endl; }
private:
Data d2;
};
int main()
{
BaseA *b=new Derived(5);
delete b;
return 0;
}
结果:
可见没有调用子类的析构函数。
有virtual时:
#include<iostream>
using namespace std;
class Data //作为下面的成员类
{
public:
Data(int x) :x(x)
{
cout << "Data cons. " << endl;
}
~Data() { cout << "Data des. " << endl; }
private:
int x;
};
class BaseA //第一个基类
{
public:
BaseA(int x) :dl(x) { cout << "BaseA cons. " << endl; }
virtual ~BaseA() { cout << "BaseA des" << endl; } //有virtual
private:
Data dl; //成员类
};
class Derived :public BaseA //注意继承顺序
{
public:
Derived(int x) :BaseA(x), d2(x) { cout << "Derived cons. " << endl; } //注意初始化顺序
~Derived() { cout << "Derived des. " << endl; }
private:
Data d2;
};
int main()
{
BaseA *b=new Derived(5);
delete b;
return 0;
}
结果:
成功通过父类指针调用子类的析构函数。
如果有不对的地方,欢迎大家批评指教!