当前位置:首页 > 工业控制 > 电子设计自动化
[导读]作者:王姗姗, 华清远见嵌入式学院讲师。 在说构造函数之前我们得先弄明白几个问题,首先是什么是类的构造函数,什么是类的成员对象,什么是基类,然后我们再来说构造函数的调用顺序。 1、 类的构造函数 构造函数的功

作者:王姗姗, 华清远见嵌入式学院讲师。

在说构造函数之前我们得先弄明白几个问题,首先是什么是类的构造函数,什么是类的成员对象,什么是基类,然后我们再来说构造函数的调用顺序。

1、 类的构造函数

构造函数的功能主要用于在类的对象创建时定义初始化的状态。它没有返回值,也不能用void来修饰,这就保证了它不仅什么也不用自动返回,而且根本不能有任何选择。构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用,一般方法在程序执行到它的时候被调用。一个类可以有多个构造函数,根据其参数个数的不同或参数类型的不同来区分它们,即构造函数的重载。

2、 类的成员对象

类包含数据成员和成员函数。当类中的成员数据是另一个类的对象时,我们就说这个类是该类的成员对象。

3、 基类

通过继承机制,可以利用已有的数据类型来定义新的数据类型。所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。我们称已存在的用来派生新类的类为基类,又称为父类。

4、 构造函数的调用顺序

我们来看下面一段代码:

class B1

{

public:

B1(int i) {cout<<"constructing B1 "<<i<<endl;}

};

class B2

{

public:

B2(int j) {cout<<"constructing B2 "<<j<<endl;}

};

class B3

{

public:

B3( ){cout<<"constructing B3 *"<<endl;}

};

class C: public B2, public B1, public B3

{

public:

C(int a, int b, int c, int d):B1(a),memberB2(d),memberB1(c),B2(b){}

private:

B1 memberB1;

B2 memberB2;

B3 memberB3;

};

void main( )

{ C obj(1,2,3,4); }

运行后的结果如下:

constructing B2 2

constructing B1 1

constructing B3 *

constructing B1 3

constructing B2 4

constructing B3 *

为什么会有以上的结果?

众所周知构造函数的执行次序如下:

调用基类构造函数,调用顺序按照他们的继承时声明的顺序。

调用内嵌成员对象的构造函数,调用顺序按照他们在类中声明的顺序。

派生类的构造函数体中的内容。

析构函数的调用顺序相反。

那么再来看以上的例子就很容易理解了。B2、B1、B3是C的基类,按照上述的顺序,我们先要构造基类,然后才是子对象,最后是其本身的构造函数所以先要执行这三个类的构造函数。在构造时按照他们在类中的顺序,首先调用B2的构造函数

B2(int j) {cout<<"constructing B2 "<<j<<endl;}

由于在默认参数列表

C(int a, int b, int c, int d):B1(a),memberB2(d),memberB1(c),B2(b){}

中,将b的值传给了B2的构造函数,b为2,故打印出:

constructing B2 2

接下来要构造的是B1了。显然在C的默认参数构造列表中将a的值传给了B1,

所以打印出:

constructing B1 1

B3在构造时没有传递参数,调用B3( ){cout<<"constructing B3 *"<<endl;}

打印出:

cout<<"constructing B3 *

这时基类的构造函数已经执行完毕,接着该处理内嵌成员对象的构造函数了。

我们看到C类有三个对象:B1 memberB1;B2 memberB2;B3 memberB3;,按照构造函数的调用顺序,我们需要按照他们在类中声明的顺序来分别构造memberB1、memberB2、 memberB3。在默认的参数列表中,用c来构造了memberB1,用d来构造memberB2,

故打印出:

constructing B1 3

constructing B2 4

constructing B3 *

最后调用本身的构造函数,由于函数体为空,故什么也没有打印出来。

总结下来,我们必须明确的是当一个类继承与基类,并且自身还包含有其他类的成员对象的时候,构造函数的调用顺序为:调用基类的构造函数->调用成员对象的构造函数->调用自身的构造函数。构造函数的调用次序完全不受构造函数初始化列表的表达式中的次序影响,与基类的声明次数和成员对象在函数中的声明次序有关。

“本文由华清远见http://www.embedu.org/index.htm提供”



来源:华清远见1次

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。 Python提供了高效的高级数据结构,还能简单有效地面向对象编程。

关键字: python 函数 对象编程

测试数据综合分析的绝佳工具,深受工程师和研究员欢迎

关键字: 后处理分析软件 向导 函数

由上图中可以知道进程地址空间中最顶部的段是栈,代码中调用函数、定义局部变量(但不包含static修饰的变量)或声明的类的实例等等都要使用栈空间,当函数执行完(也就是程序执行超过了这个函数的作用范围的时候),操作系统会把该...

关键字: 进程地址 局部变量 函数

星标/置顶 公众号,硬核文章第一时间送达!链接| https://zhuanlan.zhihu.com/p/274473971题很多,先上题后上答案,便于大家思考问题点:1、C和C的特点与区别?2、C的多态3、虚函数实现...

关键字: 腾讯 函数 进程 AI

程序接口是操作系统为用户提供的两类接口之一,编程人员在程序中通过程序接口来请求操作系统提供服务。面向过程语言最基本的单元是过程和函数。

关键字: 程序接口 过程 函数

星标「嵌入式大杂烩」,一起进步!链接:https://www.cnblogs.com/jozochen/p/8541714.html一、问题复现稳定复现问题才能正确的对问题进行定位、解决以及验证。一般来说,越容易复现的问...

关键字: 嵌入式开发 函数 代码 寄存器

基本上,没有人会将大段的C语言代码全部塞入main()函数。更好的做法是按照复用率高、耦合性低的原则,尽可能的将代码拆分不同的功能模块,并封装成函数。C语言代码的组合千变万化,因此函数的功能可能会比较复杂,不同的输入,常...

关键字: 函数 PEN C语言代码 C语言程序

Part1一、让自己习惯C条款01:视C为一个语言联邦C并不是一个带有一组守则的一体语言:他是从四个次语言(C、Object-OrientedC、Template、STL) 组成的联邦政府,每个次语言都有自己的规约。记住...

关键字: 函数 ASPECT 编译器

为什么会写篇栈变化的文章?做系统分析的话你肯定遇到过一些crash,oops等棘手问题,一般大家都会用gdb,objdump或者addr2line等工具分析pc位置来定位出错的地方。但是这些分析工具背后的本质原理就不见得...

关键字: 函数 ARM C语言 AI

前言:一转眼从事前端已经6年了,从当时的小白到如今大厂的技术专家,中间也走过不少弯路,从今天开始我会持续更新前端技术文章,并且整体的文章会进行体系梳理,整个知识体系分为:基础精讲,框架讲解,框架及工具原理,前端面试题精讲...

关键字: 函数 GE FUNCTION APP
关闭
关闭