C++面向对象-18-继承中的对象模型和继承中构造和析构顺序

2024-06-11 10:32

本文主要是介绍C++面向对象-18-继承中的对象模型和继承中构造和析构顺序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前面一篇学习了继承,知道类子类虽然继承类父类的熟悉,但是不可以访问到父类的私有成员。那么我们先来讨论一个问题,子类是否继承了父类的私有成员变量呢?然后看看继承中子类的构造和父类的构造以及析构函数的执行顺序。

 

1.通过sizeof()函数来证明子类确实继承了父类的私有成员

直接来看下面代码

#include <iostream>
using namespace std;class Base
{public :int m_A;
protected:int m_B;
private:int m_C;
};class Sun : public Base
{
public:int m_D;
};void test01()
{cout << "Size of Sun= " << sizeof(Sun) << endl;
}int main()
{test01();system("pause");return 0;
}

运行结果得到:

结果是16,也就是四个int类型,说明子类Sun继承了父类的私有非静态成员变量m_C; 那为什么子类访问不了基类的私有成员呢,原来就是C++编译器隐藏了父类的私有成员,就是不让访问,就是这么设计的,实际上子类的确继承下来了父类的私有非静态成员变量m_C。

 

2.通过vs下自带一个工具来打印一个类的对象模型

这个工具是安装了VS自带的,通过输入一个命令: cl /d1 reportSingleClassLayoutXXX 类所在文件名称

2.1 在开始菜单下找到这个工具入口

然后cd到你当前工程所在文件夹,如果不是在C盘,先需要切换到其他盘符。

输入命令,例如:cl /d1 reportSingleClassLayoutSun Sun这个类所在文件的名称

这个工具很强大,第一个红圈显示这个类大小16字节,通过看第二个红圈,告示这是父类(上面单词base class)是Base,其中继承类基类的三个成员属性,包括私有m_C。

 

3.继承中构造函数和析构函数的执行顺序

之前学习单个类的时候,我们学习类构造函数和析构函数,并且知道了是先执行构造函数,然后执行析构函数。那么这个子类继承类父类,子类的构造和父类的构造哪个先执行,通过两个析构函数怎么执行顺序。

先看看这段代码的打印顺序,我们知道现有子类还是父类对象。

#include <iostream>
using namespace std;class Base
{public:Base(){cout << "Base类的构造函数调用了" << endl;}~Base(){cout << "Base类的析构函数调用了" << endl;}};class Sun : public Base
{
public:Sun(){cout << "Sun类的构造函数调用了" << endl;}~Sun(){cout << "Sun类的析构函数调用了" << endl;}
};void test01()
{Sun s;
}int main()
{test01();system("pause");return 0;
}

运行结果

总结:

继承中的构造和析构顺序
先执行父类构造,再构造子类
先执行子类析构,再父类析构

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

这篇关于C++面向对象-18-继承中的对象模型和继承中构造和析构顺序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1050916

相关文章

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Spring Bean初始化及@PostConstruc执行顺序示例详解

《SpringBean初始化及@PostConstruc执行顺序示例详解》本文给大家介绍SpringBean初始化及@PostConstruc执行顺序,本文通过实例代码给大家介绍的非常详细,对大家的... 目录1. Bean初始化执行顺序2. 成员变量初始化顺序2.1 普通Java类(非Spring环境)(

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window