首页 > 编程语言 >【C++】继承 ⑧ ( 继承 + 组合 模式的类对象 构造函数 和 析构函数 调用规则 )

【C++】继承 ⑧ ( 继承 + 组合 模式的类对象 构造函数 和 析构函数 调用规则 )

时间:2023-10-29 13:01:17浏览次数:37  
标签:调用 函数 继承 函数调用 C++ 析构 父类 构造函数



文章目录

  • 一、继承 + 组合 模式的类对象 构造函数和析构函数调用规则
  • 1、场景说明
  • 2、调用规则
  • 二、完整代码示例分析
  • 1、代码分析
  • 2、代码示例







一、继承 + 组合 模式的类对象 构造函数和析构函数调用规则




1、场景说明



如果一个类

  • 既 继承了 基类 ,
  • 又 在类中 维护了一个 其它类型 的 成员变量 ,

那么 该类 的 构造 与 析构 , 就需要涉及到

  • 类 本身 的 构造函数 和 析构函数 ,
  • 父类 的 构造函数 和 析构函数 ,
  • 类 成员变量 的 构造函数 和 析构函数 ;


2、调用规则



在 继承 + 组合 的情况下 , 构造函数 与 析构函数 调用规则如下 :

  • 构造函数 : 父类 -> 成员 -> 自身 ;
  • 首先 , 调用 父类 构造函数 ;
  • 然后 , 调用 成员 构造函数 ; 也就是 成员变量 类型的 构造函数 ;
  • 最后 , 调用 自己 构造函数 ; 自身定义的 构造函数 ;
  • 析构函数 : 自身 -> 成员 -> 父类 ;
  • 首先 , 调用 自己 析构函数 ; 自身定义的 析构函数 ;
  • 然后 , 调用 成员 析构函数 ; 也就是 成员变量 类型的 析构函数 ;
  • 最后 , 调用 父类 析构函数 ;





二、完整代码示例分析




1、代码分析



在下面的代码中 ,

继承关系 : C 类 继承了 B 类 class C : public B , B 类 继承了 A 类 class B : public A ;

组合关系 : D 类 是一个普通类 , 在 C 类中维护了一个 D 类成员变量 ;

class C : public B {
public:
	C(int a, int b, int c) : B(a, b)
	{
		this->z = c;
		cout << "C 构造函数调用" << endl;
	}
	~C()
	{
		cout << "C 析构函数调用" << endl;
	}
public:
	int z;
	D d;
};



可根据下面的调用规则 , 分析出 C 类对象中 , 涉及到的 父类构造/析构函数 , 自身构造/析构函数 , 成员变量 构造/析构函数 的调用顺序 ;

  • 构造函数调用顺序 : 父类 -> 成员 -> 自身 ;
  • 析构函数调用顺序 : 自身 -> 成员 -> 父类 ;


2、代码示例



代码示例 :

#include "iostream"
using namespace std;

class A {
public:
	A(int a)
	{
		this->x = a;
		cout << "A 构造函数调用" << endl;
	}
	~A()
	{
		cout << "A 析构函数调用" << endl;
	}
public:
	int x;
};

class B : public A {
public:
	B(int a, int b) : A(a)
	{
		this->y = b;
		cout << "B 构造函数调用" << endl;
	}
	~B()
	{
		cout << "B 析构函数调用" << endl;
	}
public:
	int y;
};

class D
{
public:
	D()
	{
		cout << "D 构造函数调用" << endl;
	}
	~D()
	{
		cout << "D 析构函数调用" << endl;
	}
};

class C : public B {
public:
	C(int a, int b, int c) : B(a, b)
	{
		this->z = c;
		cout << "C 构造函数调用" << endl;
	}
	~C()
	{
		cout << "C 析构函数调用" << endl;
	}
public:
	int z;
	D d;
};

int main() {

	C obj(1, 2, 3);

	cout << "obj.x = " << obj.x <<
		" , obj.y = " << obj.y <<
		" , obj.z = " << obj.z << endl;


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
}

执行结果 : 下面的代码中 , 分析构造函数调用顺序 ;

  • A 和 B 的构造函数 , 是 父类构造函数 ;
  • D 构造函数 , 是 成员构造函数 ;
  • C 构造函数 , 是 自身构造函数 ;

构造函数的调用顺序为 : 父类 -> 成员 -> 自身 , 符合上述的调用原则 ;

然后分析 析构函数 调用顺序 ;

  • C 析构函数 , 是 自身构造函数 ;
  • D 析构函数 , 是 成员构造函数 ;
  • A 和 B 的析构函数 , 是 父类构造函数 ;

析构函数的调用顺序为 : 自身 -> 成员 -> 父类 , 符合上述的调用原则 ;

A 构造函数调用
B 构造函数调用
D 构造函数调用
C 构造函数调用
obj.x = 1 , obj.y = 2 , obj.z = 3
Press any key to continue . . .
C 析构函数调用
D 析构函数调用
B 析构函数调用
A 析构函数调用

【C++】继承 ⑧ ( 继承 + 组合 模式的类对象 构造函数 和 析构函数 调用规则 )_原力计划


标签:调用,函数,继承,函数调用,C++,析构,父类,构造函数
From: https://blog.51cto.com/u_14202100/8079983

相关文章

  • Java 静态代码块、代码块、构造方法和多态继承的代码执行顺序
    测试代码importlombok.Getter;publicclassExecutionOrder{{System.out.println("ExecutionOrdercode0");}static{System.out.println("ExecutionOrderstaticcode");}{System.out.println(&......
  • VS and C++ Versions
    VS版本VC版本ToolSet版本MSC版本VisualStudio66 1200VisualStudio20037 1300VisualStudio20058801400VisualStudio20089901500VisualStudio2010101001600VisualStudio2012111101700VisualStudio2013121201800......
  • python 类的继承
    假设父类:classParent(object):def__init__(self):print("打印父类")print(__class__)self.p_name="父类属性"self.p_code="10000"defget_parent_function(self):print("打印父类方法")de......
  • C++_计算机应用开发流程
    开发流程需求-痛点-不满点-构成开发需求需求排期-设计原型开发-编译-测试-发布-安装RedHat(RedhatPackageManager)的包管理规范进行打包,获取到相应的软件RPM发布包,然后使用rpm命令安装makeautotools的工具集打包的。这个工具集包含autoconf、automake等工具......
  • C++ 日期&时间
    C++日期&时间C++标准库没有提供所谓的日期类型。C++继承了C语言用于日期和实际操作的结构和函数。为了使用日期和时间相关的函数和结构,需要在C++程序中引用<ctime>头文件。有四个与时间相关的类型:clock_ttime_tsize_ttm能够把系统时间和日期表示为某种整数。结构类型tm把......
  • C++引用
    C++引用引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字,一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。C++引用vs指针引用很容易与指针混淆,它们之间有三个主要区别:不存在空引用,引用必须连接到一块合法的内存一旦引用被初始化为一个对象......
  • 面向对象(C++)
    -1待填坑:运算符重载,模板和泛型编程。文件输入输出跨文件使用全局变量应该先用extern声明如果在全局变量和全局函数前面加上static关键字,就无法在其他文件中使用这些变量和函数了。0、动态内存分配分配内存:int*p=newint(4);//注意是一个变量初值为4int*list=newint[......
  • C++指针
    C++指针学习C++指针既简单又有意思。通过指针可以简化一些C++编程任务的执行,还有一些任务,例如动态内存分配,没有指针是无法执行的。因此学习指针是很有必要的。每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。实例......
  • C++ 语法结构--堆
    1.堆介绍「堆heap」是一种满足特定条件的完全二叉树,主要可分为图8-1所示的两种类型。「大顶堆maxheap」:任意节点的值其子节点的值。「小顶堆minheap」:任意节点的值其子节点的值。堆作为完全二叉树的一个特例,具有以下特性。最底层节点靠左填充,其他层的节点都被填......
  • C++字符串
    C++字符串C++提供了两种类型的字符串表示形式:C风格字符串C++引入的string类类型C风格字符串C风格的字符串源于C语言,并在C++中继续得到支持。字符串实际上是使用Null字符终止的一堆字符数组。因此一个以NULL结尾的字符串,包含了组成字符串的字符。下面的声明和初始化创建了......