C++:派生类的生成过程(构造、析构)

目录

派生类的生成过程

派生类的构造函数与析构函数:

构造函数:

派生类+组合类的构造和析构:

构造函数和析构函数调用顺序:


派生类的生成过程

三步骤:

吸收基类(父类)成员:实现代码重用;

派生类继承了基类除了构造函数、析构函数以外的所有成员函数。

改造基类(父类)成员:改变原基类成员的访问控制权限、同名覆盖原基类的成员;

同名覆盖:在派生类中定义一个与基类同名的成员,派生类的成员将基类原成员隐藏;

对原基类被覆盖成员的访问方式:

//访问被覆盖的A类成员:

A::show();

新增派生类(子类)成员:对源代码进行扩充。

以派生类的实际需求新增加数据成员和成员函数,以增强派生类的功能

 

 

派生类的构造函数与析构函数:

因为派生类无法继承基类的构造函数与析构函数,且派生类成员由继承的基类成员、派生类新增成员共同构成,我们需自行完成构造函数实现对继承成员及新增成员的初始化、析构函数释放成员。

构造函数:

我们可以通过基类构造函数,初始化继承的基类成员

构造函数格式:

派生类名:: 派生类名(  参数列表  ):基类名(初始化列表),新成员(参数) 
{};

eg:

//继承与派生的生成过程
#include <iostream>
#include <string>
using namespace std; 


class A //基类
{
public:
	A(int i) :a(i) { cout << "A 的构造函数" << endl; };
	A() :a() { cout << "A 的默认!构造函数" << endl; };

	~A() { cout << "A 的析构函数" << endl; };

	void show()
	{
		cout << "a=" << a<<endl;
	}
private:
	int a;
};

class B :public A
{
public:
	B(int j) :b(j) 
	{ cout << "B 的构造函数" << endl; }
	//等同与:
	//B(int j):A(),b(j)
	//{cout << "A 的构造函数" << endl; }
	 
	B(int i, int j) :A(i), b(j) 
	{ cout << "B 的构造函数" << endl; }

	//同名覆盖:
	void show()
	{
		//访问基类原被覆盖成员:
		A::show();
		cout << "b=" << b << endl;
	}

	~ B() { cout << "B 的析构函数" << endl; }
private :
	int b;//新增加成员
};
int main()
{
	A a{9};
	a.show();
	B b{7,8};
	b.show();
	return 0;
}

注意:

  • 基类的构造函数必须在初始化列表内完成
    • 进入构造函数大括号内说明构造函数的功能已经实现,而基类未初始化
  • 基类如有默认构造函数时,可以省略不写
    • 该构造函数初始化,自动跳转默认构造函数

输出:

总结:派生类的构造:先调用基类构造函数、再调用派生类的构造函数,析构函数则与派生顺序相反(形成对称)

析构函数:

~类名();无差别,特殊情况区别处理;

派生类+组合类的构造和析构:

派生类:继承所得类

组合类:新增加的成员对象是另一个类的对象

//继承与派生的生成过程
//这是配置好的模板文件
#include <iostream>
#include <string>
using namespace std; 

class X 
{
public:
	X(int x) :c(x)
	{
		cout << "X(int x)构造函数" << endl;
	}
	~X()
	{
		cout << "~X()析构函数" << endl;
	}
	void show()
	{
		cout << "c=" << c << endl;
	}
private:
	int c;
};
class A //基类
{
public:
	A(int i) :a(i) { cout << "A 的构造函数" << endl; };
	A() :a() { cout << "A 的默认!构造函数" << endl; };

	~A() { cout << "A 的析构函数" << endl; };

	void show()
	{
		cout << "a=" << a<<endl;
	}
private:
	int a;
};

派生类:


class B :public A
{
public:

	B(int i, int x) : b(i), c(x)
	{
		cout << "B 的构造函数" << endl;
	}
	//等同与:
	//B(int j,int x):A(),b(j),c(x)
	//{cout << "A 的构造函数" << endl; }
	 
	B(int i,int j,int x):A(i),b(j),c(x)
	{ cout << "B 的构造函数" << endl; }

	//同名覆盖:
	void show()
	{
		//访问基类原被覆盖成员:
		A::show();
		cout << "b=" << b << endl;
		c.show();
	}

	~ B() { cout << "B 的析构函数" << endl; }
private :
	int b;//新增加成员
	X  c;  //新增组合类的成员
};
int main()
{
	/*A a{9};
	a.show();*/
	B b{7,8,9};
	b.show();
	return 0;
}

输出:

构造函数和析构函数调用顺序:

派生类构造函数执行顺序一般是:

基类(父类)、组合类、派生类

具体如下:

(1)先调用基类的构造函数

(2)然后按照数据成员的声明顺序,依次调用数据成员的构造函数或初始化数据成员;

(3)最后执行派生类构造函数的函数体。

注意:构造函数的执行顺序只与成员声明的顺序有关,而与初始化表中各项的排列顺序无关。

 

注意:派生类析构函数执行时将自动调用基类、组合类成员对象的析构函数

析构函数执行顺序:

派生类、组合类、基类

析构函数与构造函数顺序相反,形成对称

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值