"); //-->
作者:王姗姗, 华清远见嵌入式学院讲师。
在说构造函数之前我们得先弄明白几个问题,首先是什么是类的构造函数,什么是类的成员对象,什么是基类,然后我们再来说构造函数的调用顺序。
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 *
最后调用本身的构造函数,由于函数体为空,故什么也没有打印出来。
总结下来,我们必须明确的是当一个类继承与基类,并且自身还包含有其他类的成员对象的时候,构造函数的调用顺序为:调用基类的构造函数->调用成员对象的构造函数->调用自身的构造函数。构造函数的调用次序完全不受构造函数初始化列表的表达式中的次序影响,与基类的声明次数和成员对象在函数中的声明次序有关。
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
75-240W单相经济型导轨电源系列——LI(F)xxx-R2S
断电也能记录数据!ADI ADMT4000磁转数传感器
可平滑播放MPEG1、MPEG4多媒体文件的ARM板
PXI Express混合信号仪器视频教程
LabVIEW 运行性能之谜
认证技术及其在移动通信系统中的应用
能检测热电偶开路故障的电路(隔离式热电偶冷端温度补偿及信号调理器1B51)
LabVIEW 循环定时之谜
如何在A盘新建一个文件夹,列出这个文件夹里所有的子文件夹和文件?
配套AC/DC砖类电源的高性能滤波器—FC-L15HB
3W-15W低漏电流、高隔离耐压DC/DC医疗电源
LabVIEW 快速编程之谜
LabVIEW 8.5在各行业的应用集锦
软件无线电的射频天线
企业解读:人形机器人视觉领航者奥比中光
聚积科技参与infoComm 2025,参观人饱览聚积新产品系列
由数字式压力信号调理器MAX1459构成的4~20mA电流变送器的电路
由热电偶冷端温度补偿及转换器MAX6675构成的测温系统电路框图
由热电偶冷端温度补偿器AD594/595构成的摄氏温度计电路
软件无线电的开放式软件通信体系结构
高性能插件式单路驱动电源——QA-(T)-R3S系列
ugldemo在目标机上的运行问题
如何利用SDL开发TD-SCDMA高层信令
配套40A大电流机壳电源的滤波器——FC-L40Y
传统的虚拟主机早已不能满足企业网站发展的需求!
冗余度TT-VGT机器人的神经网络自适应控制
芯科科技携最新Matter演示和参考应用精彩亮相Matter开放日和开发者大会
人形机器人的假设让我们拭目以待
由热电偶冷端温度补偿器AD596/597构成温度测控仪电路
做网站,急需空间,或要找赞助?进来看看