【C++三大特性】继承

2023-05-16

如有疑问,欢迎讨论,QQ:1140004920

一、继承的概念

1.原有的类为基类,又称父类,对基类进行扩展产生的新类称为派生类,又称子类,继承可以使代码复用,并实现多态。

(1)继承的定义格式:class 派生类名:继承类型  基类名。共有三种继承类型,公有继承、保护继承、私有继承,如果不写继承类型,class默认为私有继承。struct默认为公有。最好显示写出继承方式。

(2)共有三种类成员访问限定符:公有,保护,私有,其中使用限定符保护或者私有,其成员无法在类外进行访问。

(3)定义一个简单的公有继承:

class B
{
public:
	int _a;
protected:
	int _b;
private:
	int _c;
};
class D :public B
{
public:
	int _d;
};

2.如果想用派生类去访问基类成员,是否能访问?让我们一起来看一下


根据测试,说明三种继承中,在派生类中去访问基类成员时,基类私有成员都无法访问,公有和保护都可以访问。派生类中基类的私有成员存在,但不可见。

(1)公有继承中,基类的非私有成员在派生类中的访问属性不变。

(2)保护继承中,基类的非私有成员变为派生类的保护成员。

(3)私有继承中,基类的非私有成员(公有、私有)都变为派生类中的私有成员。也就是说在类外,无法使用派生类对基类的非私有成员进行访问。

注:三种继承,不影响基类对象对成员的访问。友元关系不能继承,因为友元函数不属于类的成员函数,也就是说基类的友元不能访问子类的私有和保护成员。

二、派生类的六个默认成员函数


三、继承关系

在对派生类的对象进行初始化的时候,构造函数的调用顺序是怎样的呢?

class B
{
public:
	B()
	{
		cout << "B()" << endl;
	}
	~B()
	{
		cout << "~B()" << endl;
	}
private:
	int _a;
};
class D :private B
{
public:
	D()
	{
		cout << "D()" << endl;
	}
	~D()
	{
		cout << "~D()" << endl;
	}

private:
	int _d;
};

void FunTest()
{
	D d1;
}
其运行结果为

(1)可以看出在构造派生类对象的时候,先调用基类的构造函数,但事实如此吗?经过进一步调试。发现在构造派生类对象的时候,先调用的是派生类的构造函数,然后到达派生类参数列表处,在调用基类的构造函数,完成对基类对象的构造,然后进行派生类对象的构造函数,执行类构造函数体。

(2)根据分析,析构函数的调用过程是倒着的,先析构派生类的,然后析构基类的。如果有派生列对象d1、d2,那么先释放d2,在释放d1。



(3)如上图,子类和父类有同名成员,它将优先访问派生类的对象。如果想访问基类的那个同名成员,可以使用(基类::基类成员)。注意在实际继承中,最好不要定义同名成员。

同名隐藏与类型变量无关,与返回值无关。同名变量如此,同名函数也如此。

(4)在书写基类和派生类的时候也要注意一下几点问题,第一基类没有定义有参数的构造函数,子类也不用定义。第二基类定义了有参数的构造函数,派生类就一定得定义构造函数(派生类的默认构造函数没有参数,不能调用有参的基类)


(5)如上图,基类没有缺省构造函数(带参数列表),派生类必须在初始化列表处显示给出基类名和参数列表。没有合适的默认参数可用,因为派生类刚才调用了一次基类的构造函数,这里默认的是如果基类没有缺省的构造函数,就不会默认合成基类的构造函数,所以在构造派生类的时候初始化列表加上基类的参数。

四、继承--赋值兼容规则(public继承)


(1)根据上图,说明子类的对象可以给父类对象赋值,但是父类的对象不能给子类赋值。因为父类给子类的对象赋值时,子类只能访问到b1,去访问d1的时候会发生错误


(2)根据上图,说明父类的指针可以指向子类的对象,但是子类的指针不能指向父类的对象。因为子类的指针指向父类的对象时,它访问不到d1。反之父类的指针指向基类的对象时,父类只会访问自己的成员,不会访问出错。可以使用强制类型转换,使子类的指针指向父类的对象,但这样不安全,不推荐使用。

五、继承与静态成员

基类定义了一个静态成员,需要在类外进行声明,在整个继承体系中,只有这样一个成员。


六、继承的三种类型

(1)单继承;一个子类只有一个父类

(2)多继承:一个子类有两个或以上的父类

(3)菱形继承:由单继承和多继承构成


当创建一个子类d的对象,去访问基类_a的时候,发生了错误,因为基类成员在派生类里有两份,发生了二义性与数据冗余的问题,而且浪费空间。为了解决这个问题,我们引入了虚拟继承。

七、菱形虚拟继承

一般实际应用不定义这样复杂的继承体系,虽然解决了二义性与数据冗余的问题,但也使性能降低

class a
{
public:
	int _a;
};
class b :virtual public a
{
public:
	int _b;
};
class c :virtual public a
{
public:
	int _c;
};
class d :public b, public c
{
public:
	int _d;
};
int main()
{
	d d1;
	d1._a = 1;
	d1._b = 2;
	d1._c = 3;
	d1._d = 4;
	cout << sizeof(d1) << endl;
	getchar();
	return 0;
}

根据运行图,发现菱形继承多了4个字节,这四个字节是什么呢?


原来里面存放的是偏移量表格的地址,偏移量表格存放的是相对于自己的偏移量和相对于基类的偏移量,这样c和d指向同一个基类,很好地解决了二义性问题。



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++三大特性】继承 的相关文章

  • QT QWebEngineProcess注意事项及扫码登录回调

    一 pro文件中需要添加模块 二 程序打包 除了使用windeployqt exe打包依赖库以外 xff0c 还需要手动添加两项文件 第一步 xff1a 在你程序bin目录下的translations文件中添加文件夹qtwebengine
  • QT 防止按钮快速重复点击

    一 实现间隔一秒只能点击一次按钮 xff08 没到时间之前 xff0c 点击不能按 xff09 span class token keyword void span span class token class name MainWindo
  • QT QButtonGroup 与 QStackedWidget 实现菜单(Tab)切换

    一 效果图 三个菜单互斥点击 xff0c 点击后跳转至相应页面 二 QButtonGroup 按钮互斥 1 UI结构 2 代码 span class token keyword void span span class token func
  • 对于程序多核优化的思考

    针对处理器的多核心多线程进行优化 现在的处理器很少有单核的 xff0c 2核的都很少了 在用python计算2的10000000次方的时候 xff0c 我观察了我的任务管理器 xff0c 首先第3个线程的使用率达到了100 xff0c 然后
  • QT QListWidget的添加与删除,滚动条显示或隐藏,判断是否滑到顶部或底部,并使QListWidgetItem自适应大小

    注意 xff1a QListWidget添加子Item时 xff0c 最外层最好设置完整背景颜色 xff0c 否则移入Item会自带淡蓝色背景 一 QListWidget 中使 QListWidgetItem自适应大小 父部件ListWid
  • QT 网络请求设置自定义cookie请求头失败的问题

    文章目录 一 背景二 示例代码1 自己组装HTTP请求 xff08 成功 xff09 2 采用项目网络组件库 xff08 失败 xff09 3 解决办法 xff08 成功 xff09 一 背景 我准备在每一次HTTP请求头中加入自己定义的c
  • QT 三角气泡提示框(文字自适应、自定义三角位置)

    文章目录 一 效果图二 实现代码1 调用示例2 BubbleTipsWidget h3 BubbleTipsWidget cpp 一 效果图 二 实现代码 1 调用示例 span class token keyword void span
  • QT 代码添加QScrollArea

    一 QScrollArea 一 这是一个控件容器类 xff0c 可以在UI中直接拖拽 xff0c 也可以使用代码进行添加 xff0c 当我们UI添加时 xff0c QScrollArea这个容器套了两层 xff0c 我们放入的控件 xff0
  • QML入门----创建qml项目(一)

    文章目录 导语一 选择菜单二 选择文件类型三 填写项目名称四 项目创建成功五 Hello World六 运行图 导语 今天开始学习qml xff0c 从hello world开始 xff0c 本来计划之前开始学的 xff0c 但是看了好多资
  • QML入门----基本语法(二)

    文章目录 基础语法1 import 导入语句2 Loader 一 类型二 对象1 id2 属性 xff08 property xff09 3 信号和信号处理器特性4 方法特性 function5 附加属性和附加信号处理器6 枚举 四 注释五
  • QML入门----图形动画基础(一)

    文章目录 一 图形动画基础1 颜色2 渐变 xff08 Gradient xff09 二 图片1 图片2 边界图片3 动态图片 三 缩放 旋转 平移变换1 使用属性2 高级变换 xff08 Transform xff09 四 状态改变使用过
  • QT Signal and slot arguments are not compatible

    一 原因 信号和槽绑定的参数不同 signals span class token operator span span class token keyword void span span class token function run
  • QML入门----图形动画基础(二)

    文章目录 导语一 混合效果二 颜色效果1 亮度对比度 xff08 BrightnessContrast xff09 2 颜色叠加3 着色4 饱和度 三 渐变效果 xff08 Gradient xff09 四 阴影效果五 模糊效果六 动感模糊
  • EXCEL基本办公操作 (求和、相除、填充日期、交换列、排序)

    文章目录 一 求和二 相除三 自动填充日期四 交换列五 进行排序 一 求和 1 拖动鼠标选中 2 同时按住 alt 跟 61 二 相除 假如要计算A列除以B列 1 先选中显示结果的框 2 在上面的框输入 61 号 xff0c 然后点击A1位
  • Ubuntu的VirtualBox虚拟机怎么识别物理机的U盘?我教你。

    首先确保 你的VBOX虚拟机安装了扩展 1 到官网上下载扩展吧 2 用VBOX打开扩展包 3 打开VBOX管理器 xff0c 点击设置 4 新建一个usb筛选器 xff0c 名字随便起 最后点击确定 正常关闭 你的虚拟机 xff0c 然后重
  • QML入门----设计器详解(拖拽添加控件)

    文章目录 导语1 基本视图2 文件类型 一 界面说明1 库 xff08 Library xff09 2 导航 xff08 Navigator xff09 3 属性 xff08 Properties xff09 4 连接视图 导语 设计器的基
  • C++11 非常方便的特性

    文章目录 C 43 43 11一 nullptr1 含义2 作用3 NULL存在的问题 二 auto1 含义2 限制3 使用场景 三 lambda1 含义2 优点3 用法 四 基于范围的for循环1 作用2 用法3 循环内更改数组 C 43
  • QML入门----C++与QML交互快速应用

    文章目录 前言一 Qt中有关QML的C 43 43 类1 QQmlEngine2 QQmlContext3 QQmlComponent4 QQmlExpresssssion 二 其他1 使用C 43 43 属性 xff08 Q PROPER
  • QML错误:Component is not ready

    一 原因 终极原因 xff1a 组件没有构建好 xff0c 有可能是加载的QML路径不对 xff0c 或者是QML代码错误 xff0c 或者是QML组件还没有加载完 二 解决办法 打印详细错误 QQmlEngine engine span

随机推荐

  • QT 打开程序闪烁cmd窗口

    包含多种原因 xff0c 我的原因是Pro文件多写了一些其他的 xff0c 删除了下面这句OK了 DISTFILES span class token operator 43 span span class token operator 6
  • QT UTC(T和Z格式)时间转换为北京时间

    一 UTC 协调世界时 xff0c 又称世界统一时间 世界标准时间 国际协调时间 由于英文 xff08 CUT xff09 和法文 xff08 TUC xff09 的缩写不同 xff0c 作为妥协 xff0c 简称UTC 和北京时间相差八小
  • QT 文件操作大全

    文章目录 常用文件模式一 创建文件二 读文件三 写文件四 清空文件夹五 计算文件夹个数六 计算文件夹总大小七 转换大小为B KB M G八 批量修改文件名 常用文件模式 模式含义QIODevice ReadOnly只读方式QIODevice
  • QT QScrollArea 滑动到指定item位置

    一 QT自带的api QListWidget QTableWidget QTreeWidget都有自带的api可以调用 xff0c 如下示例 但是当自定义一个QScrollArea区域 xff0c 布局中插入多个item时 xff0c 就需
  • 马克飞象常用操作(markdown )

  • QT 移入控件展示卡片

    功能 xff1a 移入widget显示卡片 xff0c 并且可以进入卡片不消失 xff08 widget与卡片距离离得很近 xff09 xff0c 移出卡片才离开 span class token keyword bool span spa
  • 树莓派pico入门第一站:让主板上的小灯闪起来。(附代码)

    首先配置你的树莓派pico xff0c 把它插在你的电脑上 xff0c 你的电脑会多出来一个 U盘 xff0c 把这个文件复制 xff0c 粘贴 到你的树莓派pico里面 xff0c 你多出来的 U盘 会自动 消失 xff0c 这时候 xf
  • QT 网格布局插入固定列数的item

    一 场景 在网格布局插入固定列数的item xff0c 比如三列item xff0c 根据item的总数计算 span class token macro property span class token directive hash s
  • QT QMetaEnum枚举与字符串互转

    一 示例 span class token macro property span class token directive hash span span class token directive keyword include spa
  • QT 抓取widget转换为图片

    QString folder span class token operator 61 span span class token class name QStandardPaths span span class token operat
  • window11 安装linux子系统(一键安装)并连接到vs code

    文章目录 一 window 使用linux环境的几种方式二 安装wsl1 进入这个目录下 xff0c 将cmd exe已管理员身份运行2 命令行输入以下命令 xff0c 然后重启计算机3 再次已管理员身份打开 xff0c 执行命令 xff0
  • QT 利用URL Protocol实现网页调起本地程序

    一 QT 安装时脚本注入注册表或者自己添加 span class token comment 依次为目录 键 值 xff0c 34 URL Protocol 34 这个键必须有 span WriteRegStr HKCR span clas
  • PC 配置jenkins自动打包

    文章目录 一 下载jenkins运行环境二 下载jenkins三 安装 qt 5 12 2 和 VS 2017四 安装git并配置gitlab五 jenkins配置git 一 下载jenkins运行环境 java jdk 11 镜像下载地址
  • 心系Flyme

    我来自陕西省神木县 xff0c 大学我考入了陕西科技大学 xff0c 成为了一名信息与计算科学专业的学生 xff0c 希望在以后的道路中 xff0c 通过我自己的努力 xff0c 提升自己的价值 在大二大三学习编程 xff0c 希望自己可以
  • C语言的编译链接过程

    编写的一个C程序 xff08 源程序 xff09 xff0c 转换成可以在硬件上运行的程序 xff08 可执行程序 xff09 xff0c 需要进行翻译环境和运行环境 翻译环境则包括两大过程编译和链接 xff0c 经过编译和链接过程便可形成
  • 函数的调用过程(栈帧的创建和销毁)

    为了更好地认识函数的调用过程 xff0c 我们可以用反汇编代码去理解学习 一 基本概念 1 栈帧 xff08 过程活动记录 xff09 xff1a 是编译器用来实现函数调用的一种数据结构 xff0c 每个栈帧对应一个未运行完的函数 xff0
  • 树莓派pico刚买来怎么用?

    第一次使用 xff0c 首先按住主板上的白色按钮 xff0c 然后另一只手把数据线插在主板上 xff0c 直到你的电脑提示有新设备输入 xff0c 提示可以是声音 xff0c 可以是设备管理器多了一个U盘 要想得到提示 xff0c 你要打开
  • C语言动态顺序表

    顺序表是将表中的节点依次存放在计算机内存中一组地址连续的存储单元中 xff0c 表可以动态增长 xff0c 尾插元素 xff0c 尾删元素 xff0c 头插元素 xff0c 头删元素 xff0c 打印元素 xff0c 查找元素 xff0c
  • C语言笔记1

    假定程序运行环境为VC6 0 xff0c 缺省为四字节对齐 xff0c CPU xff08 32小字节序处理器 xff09 1 char x 61 34 ab0defg 34 char y 61 39 a 39 39 b 39 39 0 3
  • 【C++三大特性】继承

    如有疑问 xff0c 欢迎讨论 xff0c QQ xff1a 1140004920 一 继承的概念 1 原有的类为基类 xff0c 又称父类 xff0c 对基类进行扩展产生的新类称为派生类 xff0c 又称子类 xff0c 继承可以使代码复