二、继承类型、派生类的构造函数和析构函数

一.继承的分类

  • 单继承:一个派生类只有一个直接基类的情况称为单一继承(single-inheritance)。
  • 多重继承:如果一个派生类可以同时有多个基类,称为多重继承(multiple-inheritance),这时的派生类同时得到了多个已有类的特征。

1.在使用派生类实例化对象时调用了父类的构造函数和派生类的构造函数,下面是单继承情况:

#include<iostream>
using namespace std;

class Base
{
public:
	Base():x(0)
	{
		cout<<"构造Base"<<endl;
	}
	~Base()
	{
		cout<<"析构Base"<<endl;
	}
private:
	int x;
};

class DD:public Base
{
public:
	DD():y(0)
	{
		cout<<"构造DD"<<endl;
	}
	~DD()
	{
		cout<<"析构DD"<<endl;
	}
private:
	int y;
 } ;
 int main()
 {
 	DD d;//实例化d对象,将先调动父类的构造函数构造一个父类对象,则,d对象的数据成员包含了x,y 
 	return 0;
  } 

此时派生类对象d 的内存布局为

2.多继承情况下:派生类类实例化对象时,调用基类构造函数的顺序:按它们在派生类定义的先后顺序,顺序调用。

#include<iostream>
using namespace std;


class Base1
{
public:
	Base1():x1(0)
	{
		cout<<"构造Base1"<<endl;
	}
	~Base1()
	{
		cout<<"析构Base1"<<endl;
	}
private:
	int x1;
};
class Base2
{
public:
	Base2():x2(0)
	{
		cout<<"构造Base2"<<endl;
	}
	~Base2()
	{
		cout<<"析构Base2"<<endl;
	}
private:
	int x2;
};
class Base3
{
public:
	Base3():x3(0)
	{
		cout<<"构造Base3"<<endl;
	}
	~Base3()
	{
		cout<<"析构Base3"<<endl;
	}
private:
	int x3;
};
class DD:public Base1,public Base2,public Base3//注:若写成: public Base, Base1, Base2,则D私有继承Base1和Base2 
{
public:
	DD():y(0)
	{
		cout<<"构造DD"<<endl;
	}
	~DD()
	{
		cout<<"析构DD"<<endl;
	}
private:
	int y;
 } ;
 int main()
 {
 	DD d;//实例化d对象,将先调动父类的构造函数构造3个父类对象,则,d对象的数据成员包含了x1,x2,x3,y 
 	return 0;
  } 

此时派生类对象d 的内存布局为

3.多继承情况下:当子类中包含有对象形式的数据成员时,调用父类的构造函数顺序为:按它们在类定义中声明的先后顺序,顺序调用。

#include<iostream>
using namespace std;


class Base1
{
public:
	Base1() :x1(0)
	{
		cout << "构造Base1" << endl;
	}
	~Base1()
	{
		cout << "析构Base1" << endl;
	}
private:
	int x1;
};
class Base2
{
public:
	Base2() :x2(0)
	{
		cout << "构造Base2" << endl;
	}
	~Base2()
	{
		cout << "析构Base2" << endl;
	}
private:
	int x2;
};
class Base3
{
public:
	Base3() :x3(0)
	{
		cout << "构造Base3" << endl;
	}
	~Base3()
	{
		cout << "析构Base3" << endl;
	}
private:
	int x3;
};
class DD :public Base1, public Base2, public Base3//注:若写成: public Base, Base1, Base2,则D私有继承Base1和Base2 
{
public:
	DD()
	{
		cout << "构造DD" << endl;
	}
	~DD()
	{
		cout << "析构DD" << endl;
	}
private://按它们在类定义中声明的先后顺序,顺序调用父类的构造函数 

	Base3 d3;
	Base2 d2;
	Base1 d1;
};
int main()
{
	DD d;//实例化d对象,将先调动父类的构造函数构造3个父类对象,则,d对象的数据成员包含了d1.d2.d3
	return 0;
}

此时派生类对象d 的内存布局为

特别注意:

  • 在派生类构造函数中,只要基类不是使用缺省构造函数都要显式给出基类名和参数表。若使用缺省构造函数,则可以不用显式给出基类名及参数表。
  • 如果基类没有定义构造函数,则派生类也可以不定义,全部采用系统给定的缺省构造函数。
  • 如果基类定义了带有形参表的构造函数时,派生类就应当定义构造函数。

例如

#include<iostream>
using namespace std;


class Base1
{
public:
	Base1(int d1):x1(d1)
	{
		cout<<"构造Base1"<<endl;
	}
	~Base1()
	{
		cout<<"析构Base1"<<endl;
	}
private:
	int x1;
};
class Base2
{
public:
	Base2(int d2):x2(d2)
	{
		cout<<"构造Base2"<<endl;
	}
	~Base2()
	{
		cout<<"析构Base2"<<endl;
	}
private:
	int x2;
};
class Base3
{
public:
	Base3(int d3):x3(d3)
	{
		cout<<"构造Base3"<<endl;
	}
	~Base3()
	{
		cout<<"析构Base3"<<endl;
	}
private:
	int x3;
};
class D:public Base1,public Base2,public Base3//注:若写成: public Base, Base1, Base2,则D私有继承Base1和Base2 
{
public://若父类没有缺省构造函数,子类的构造函数必须通过参数列表的形式进行初始化对象
       //显式给出基类名和参数表,对象名和参数表
       //基类名,成员对象名的次序可以随意,这里的次序与调用次序无关。  
	D(int data):Base1(data),Base2(data),Base3(data),d1(data),d2(data),d3(data)
	{
		cout<<"构造D"<<endl;
	}
	~D()
	{
		cout<<"析构D"<<endl;
	}
private://按它们在类定义中声明的先后顺序,顺序调用父类的构造函数 
	
	Base3 d3;
	Base2 d2;
	Base1 d1;
 } ;
 int main()
 {
 	D d(10);//实例化d对象,将先调动父类的构造函数构造3个父类对象,则,d对象的数据成员包含了x1,x2,x3,y 
 	return 0;
  } 

总结:

  • 继承分为单继承和多继承  
  • 派生类类实例化对象时,调用基类构造函数,按它们在派生类中定义的先后顺序,顺序调用   
  • 派生类中数据成员为基类的对象时,调用成员对像的构造函数,按他们在类定义中声明的先后顺序,顺序调用
  • 若父类没有缺省构造函数,子类的构造函数必须通过参数列表的形式进行初始化对象
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值