继承下构造函数的执行顺序
这里先给出结论,在贴出代码与执行结果~
一个派生类构造函数的执行顺序如下:
第一步执行:虚拟基类的构造函数(多个虚拟基类则按照继承的顺序执行构造函数)。
第二步执行:基类的构造函数(多个普通基类也按照继承的顺序执行构造函数)。
第三步执行:类类型的成员对象的构造函数(按照初始化顺序)。
第四部执行:派生类自己的构造函数。
如果一个派生类不仅继承于一个基类,而且还有这个基类的成员对象,那么会进行两次构造函数的执行(一个用于初始化派生类中基类部分的内部成员,另一个是初始化派生类的基类类型成员变量的内部成员),详细看派生类Son2的执行结果。
你
下面声明了A,B,C,D,Object1,Object2留个基类以及Son1,Son2,Son3,Son4,Son5(Son5是一个错误的例子,编译不能通过)
每个基类都有两个构造函数,默认的构造函数不接受参数,输出的Default+字符串
带参数的输出的自己类的特有信息。
(为了方便观看,我在后面会再贴一下结论)
参考Son1:可以验证上述派生类构造函数的执行顺序;
参考Son2:可以验证构造函数是严格照上面所说的顺序执行,与初始化的顺序无关。同时,如果不显示的执行基类构造函数的初始化,就会按照顺序调用默认的构造函数。
参考Son3:可以说明继承下执行的构造函数与类类型的成员变量的构造函数是占用两个不同的内存地址空间,二者不会相互影响。
参考Son4:可以说明,无论是否显示的初始化类类型的成员变量,都会按照成员变量在类中的声明顺序执行构造函数。
参考Son5:这个解决了我之前的疑问,如果在派生类的构造函数中初始化类类型的成员对象会怎么样,发现这样是不可取的,因为在类的声明中是不可以实际分配内存的,但是可以声明。
(关于Son5的理解需要进一步阐明:这里可能涉及到了C++内存分配,拷贝赋值的原理,如果不是很懂的话这里我们暂且按我说的方式去理解。)
classA
{
public:A(intnum){Show();}A(){cout<<"Defaultaaa"<<endl;}voidShow(){cout<<"aaa"<<endl;}
};
classB
{
public:B(intnum){Show();}B(){cout<<"Defaultbbb"<<endl;}voidShow(){cout<<"bbb"<<endl;}
};
classC
{
public:C(intnum){Show();}C(){cout<<"Defaultccc"<<endl;}voidShow(){cout<<"ccc"<<endl;}
};
classD
{
public:D(intnum){Show();}D(){cout<<"Defaultddd"<<endl;}voidShow(){cout<<"ddd"<<endl;}
};
classObject1
{
public:Object1(intnum){Show();}Object1(){cout<<"DefaultObject1"<<endl;}voidShow(){cout<<"Object1"<<endl;}
};
classObject2
{
public:Object2(intnum){Show();}Object2(){cout<<"DefaultObject2"<<endl;}voidShow(){cout<<"Object2"<<endl;}
};
classSon1:publicA,virtualpublicB,publicC,virtualpublicD
{
public:
Son1():A(1),B(1),C(1),D(1),ob1(1),ob2(1){cout<<"son1"<<endl;}Object1ob1;Object2ob2;
};
classSon2:publicA,virtualpublicB,publicC,virtualpublicD
{
public:Son2():C(1),A(1),ob1(1),ob2(1){ //结果仍然是先执行A的构造函数,其次是C的,证明与初始cout<<"son2"<<endl; //化的顺序无关}Object1ob1;Object2ob2;
};
classSon3:publicA,virtualpublicB,publicC,virtualpublicD,virtualpublicObject1,publicObject2
{
public:Son3():ob1(1),ob2(1){cout<<"son3"<<endl;}Object1ob1;Object2ob2;
};
classSon4:publicA,virtualpublicB,publicC,virtualpublicD,virtualpublicObject1,publicObject2
{
public:Son4():ob2(1){ //注意,如果Object1没有默认构造函数,这里将无法编译通过cout<<"son4"<<endl;}Object1ob1;Object2ob2;
};
//class Son5:publicA,virtual public B,publicC,virtual public D
//{
//public:
// Son5():A(1),B(1),C(1),D(1){
// cout<<"son5"<<endl;
// ob2=ob1; //这里编译不通过,没有与这些操作数匹配的”=”运算符(二者类型不同,需要重新定义‘=’)
// ob1(1);
// ob2(2); //这里编译不通过,在没有适当的operate()的情况下调用类类型对象
// }
// Object1 ob1(1); // 这里编译不通过,因为类的成员声明不需要分配内存,这样写就相当于执行//构造函数并分配内存了
// Object2 ob2;
//};
int_tmain(intargc, _TCHAR* argv[])
{
cout<<"------------SON1------------"<<endl;Son1son1;cout<<"------------SON2------------"<<endl;Son2son2;cout<<"------------SON3------------"<<endl;Son3son3;cout<<"------------SON4------------"<<endl;Son4 son4;Object1obj;//son4.ob1(1); //这句话是错误的编译不通过,在没有适当的operate()的情况下调用类类型对象son4.ob1=obj;system("pause"); //这句只是为了让cmd停留显示,以免闪退(VS控制台程序需要)return 0;
}
以上代码是在VS2012ConsoleApplication控制台下编译测试的,结果如下:
再贴一遍:
参考Son1:可以验证一开始介绍的派生类构造函数的执行顺序;
参考Son2:可以验证构造函数是严格照上面所说的顺序执行,与初始化的顺序无关(尽管表面上C比A初始化的要早)。同时,如果不显示的执行基类构造函数的初始化,就会按照顺序调用默认的构造函数。
参考Son3:可以说明继承下执行的构造函数与类类型的成员变量的构造函数是占用两个不同的内存地址空间,二者不会相互影响。
参考Son4:可以说明,无论是否显示的初始化类类型的成员变量,都会按照成员变量在类中的声明顺序执行构造函数。
参考Son5:这个解决了我之前的疑问,如果在派生类的构造函数中初始化类类型的成员对象会怎么样,发现这样是不可取的,因为在类的声明中是不可以实际分配内存的,但是可以声明。
继承下构造函数的执行顺序相关推荐
- C++三大继承构造函数的执行顺序详解
写的挺好的,关于继承和构造函数的先后顺序问题. 转自: http://blog.csdn.net/daheiantian/archive/2011/02/18/6438782.aspx 一.单继承 核 ...
- java构造函数的执行顺序,java构造函数和初始化函数的执行顺序
1,静态变量.静态代码块.变量.普通代码块.mian方法.构造函数的执行顺序是:(静态变量.静态代码块)> main方法 >(变量.普通代码块)>构造函数. 2,如果子类调用了 ...
- 派生类构造函数的执行顺序
一个派生类构造函数的执行顺序如下: 虚拟基类的构造函数(多个虚拟基类则按照继承的顺序执行构造函数). 基类的构造函数(多个普通基类也按照继承的顺序执行构造函数). 对象的vptr被初始化: 成员对象构 ...
- 构造代码块、静态代码块、无参构造函数和有参构造函数的执行顺序
一直对构造代码块.静态代码块.无参构造函数和有参构造函数的执行顺序和执行次数混淆不清,所以记录一下它们的执行顺序以及执行次数.记录的不是很详细,留待补充. 代码: package com.yoko.t ...
- java 构造函数的执行顺序
在此我用类似<Thinking in Java>的一个例子来说明 pakage com.yqs.test class Milk { publcic Milk() { System.out. ...
- 静态代码块、非静态代码块、构造函数三者执行顺序
主要探讨一下关于静态代码块,非静态代码块,构造函数的执行顺序. 如有错误,欢迎指出. 首先: 静态成员变量和静态代码块的优先级是一样的,先定义的先执行. 在创建一个对象的时候会执行非静态代码块和构造函 ...
- 继承中的构造方法执行顺序
继承中的构造方法执行顺序 在子父类中,创建子类对象,调用子类的构造方法, 在子类的构造方法的第一行代码如果没有调用父类的构造或者没有调用子类的其他构造,则默认调用父类无参构造. 为什么要调用父类构造? ...
- Mingw下g++编译执行顺序错误
今天写一个简单的线性表时,用Mingw中的g++编译.调试.运行时发现一个奇怪的现象:程序的执行顺序与实际编写顺序不一致. 编译环境:代码编写 win7下 editplus + Mingw 4. ...
- C++虚继承中构造函数和析构函数顺序问题以及原理
多重继承的问题:多个类B,C,-继承同一个类A导致如果X继承了B,C,-那么在X中将还有多个A中成员的拷贝,如果想要访问A中的成员如果不加名字空间将会导致二义性,这种拷贝大多是没有实际意义的,为了避免 ...
最新文章
- 机器学习——XGBoost大杀器,XGBoost模型原理,XGBoost参数含义
- 【Java_基础】Java中Native关键字的作用
- 指针 混用 迭代器_对比 C++ 和 Python,谈谈指针与引用
- relative会脱离文档流吗_脱离华为之后,高通伸来援手,荣耀40会搭载骁龙888吗?...
- 网络安全技术文章征稿启事
- java epoll select_字节跳动高频面试题,操作系统/算法/Java等。
- 当爬虫工程师遇到 CTF丨2021 年 B 站 1024 安全攻防题解
- PspNet在MMsegmentation框架下成功训练Pascal VOC2012数据集及踩坑实录
- ABP框架源码学习之修改默认数据库表前缀或表名称
- 用计算机运算符编写检索式,检索式
- 数据库系统概论(高级篇)
- 珠机妙算益智桌面游戏python_十款3D打印的经典桌面游戏
- 卸载Docker CE
- python解析FreeMind思维导图
- python调用shell命令
- 分享一款快速、免费抠图工具——凡科快图
- linux软中断是什么机制,Linux软中断原理浅析
- 三维设计SolidWorks
- 单片机c语言屏蔽第四位,单片机C语言学习
- 实验吧[WEB]——what a fuck!这是什么鬼东西?