C++基础知识(六:继承)
首先我们应该知道C++的三大特性就是封装、继承和多态。
此篇文章将详细的讲解继承的作用和使用方法。
- 继承
一个类,继承另一个已有的类,创建的过程
父类(基类)派生出子类(派生类)的过程
继承提高了代码的复用性
【1】继承的格式
class 类名:父类名
{}; 【2】继承的权限
class 类名:继承的权限 父类名
{};如果不写继承方式,默认是私有继承 父类中的权限 public|private|protected public|private|protected public|private|protected
继承方式 public private protected
子类中的权限 public|不能访问|protected private|不能访问|private protected|不能访问|protected
【3】继承时类中的特殊成员函数
特殊的成员函数不会被继承
构造函数:
- 需要在子类中显性调用父类的构造函数(初始化列表中)(透传构造)
- 透传构造
- 继承构造
- 委托构造
需要在子类中显性调用父类构造函数的场合:
父类中只有有参构造 ----->子类在创建类对象时,必须手动调用父类的构造函数
#include <iostream>using namespace std;class Father
{
public:int age;char c;Father(int a,char c):age(a),c(c){cout << "Father有参" << endl;}
};class Child:public Father //----->私有继承
{int high;
public:void show(){
cout << c << endl;}
};int main()
{//Child c1; //error,因为父类只有有参构造,而子类中没有提供能够调用父类有参构造的构造函数,不能成功创建父类的空间//Father f1;
c1.age;
cout << sizeof (Father) << endl;
cout << sizeof (Child) << endl;return 0;
} i)透传构造
在子类构造函数的初始化列表中,显性调用父类的构造函数

ii)继承构造
C++支持
不用在子类中再写一遍父类的构造函数
使用:using Father::Father; ----->在子类中使用父类的构造函数
直接使用继承构造的方式,不能对子类成员初始化
继承构造本质上并不是把父类中的构造函数继承给子类,编译器自动根据父类中构造函数的格式,提供出派生的构造函数(个数和参数都和父类中的构造函数一致),主要还是通过透传构造创建父类的空间

#include <iostream>
using namespace std;class Father
{
public:int age;char c;
// Father(){cout << "Father无参" << endl;}Father(int a,char c):age(a),c(c){cout << "Father有参两个参数" << endl;}Father(char c):c(c){cout << "Father有参一个参数的" << endl;}Father(Father &other):age(other.age),c(other.c){cout << "Father拷贝" << endl;}
};class Child:public Father //----->私有继承
{
private:int high;//父类中的public成员age,通过公有继承,仍然是publicusing Father::age; //把父类中公有继承下来的age成员,在子类中改成私有权限
public:void show(){
cout << c << endl;}//子类的无参构造,但是显性调用父类的有参构造还给了默认值//透传构造
// Child():Father(12,'a'){cout << "Child无参构造" << endl;}
// Child(int a,char c,int h):Father(a,c),high(h)
// {cout << "Child有参构造" << endl;}//父类中的所有构造函数,都被继承到了子类中using Father::Father; //更高效一些
};int main()
{
Child c1(10);
Child c2(20,'z');
Child c3 = c2;//Father f1;//c1.age;
cout << sizeof (Father) << endl;
cout << sizeof (Child) << endl;return 0;
}
iii)委托构造
一个类的情况,并不直接通过无参构造实例化对象,而是无参构造委托了有参构造,实例化对象

继承时的情况

Child():Child(10){cout << "Child无参构造" << endl;} //Child c1
Child(int a):Father(12,'a'),high(a)
{cout << "Child有参构造一个参数" << endl;} iv)拷贝构造
需要在初始化列表中显性调用父类的拷贝构造,传other对象到父类的拷贝构造中
Father(Father &other):age(other.age),c(other.c){cout << "Father的拷贝构造" << endl;}
Child(Child &other):Father(other),high(other.high){} 【4】继承时构造和析构的时机
继承关系,可以理解为包含关系
子类在继承父类时,会把父类中的成员保留一份,再来创建子类自己的成员
父类先构造,子类后构造
子类先析构,父类后析构
#include <iostream>using namespace std;
class F
{int *p;
public:F():p(new int){cout << "F无参构造" << endl;}~F(){delete p;
cout << "F析构函数" << endl;}
};
class C:public F
{int *p;
public:C():p(new int){cout << "C无参构造" << endl;}~C(){delete p;
cout << "C析构函数" << endl;}
};int main()
{
C *p1 = new C;delete p1; //空间释放时,会自动调用析构函数,无需手动调用
p1 = nullptr;return 0;
}
【5】父子类中存在同名成员问题
访问时不会发生冲突,默认访问子类的
#include <iostream>
using namespace std;
class F
{
public:int *p;F():p(new int){cout << "F无参构造" << endl;}~F(){delete p;
cout << "F析构函数" << endl;}
};
class C:public F
{
public:int *p;C():p(new int){cout << "C无参构造" << endl;}~C(){delete p;
cout << "C析构函数" << endl;}
};int main()
{
C *p1 = new C;*(p1->p) = 90;
cout << *(p1->p) << endl; //子类成员和父类成员同名,默认优先访问子类成员
cout << *(p1->F::p) << endl; //通过域限定符访问父类的成员delete p1; //空间释放时,会自动调用析构函数,无需手动调用
p1 = nullptr;return 0;
} - 多重继承
一个子类,继承自多个基类
【1】格式
class 类名:继承权限 父类名,继承权限 父类名····
{} 【2】当多个父类中包含同名成员
多个父类中包含同名成员,通过域限定符访问指定的父类中成员
#include <iostream>using namespace std;class Room
{
public:void clean(){
cout << "打扫房间" << endl;}
};
class BedRoom
{
public:void play(){
cout << "可以玩游戏" << endl;}void clean(){
cout << "打扫卧室" << endl;}
};//Home类公共继承字Room和BedRoom类
class Home:public Room,public BedRoom
{
};int main()
{
Home h1;
h1.play();
h1.Room::clean();
h1.BedRoom::clean();return 0;
} - 菱形继承(钻石继承)
【1】格式
A ----->公共基类/ \
B C ------>中间子类
\ /
D ------>汇集子类 汇集子类中,会包含两份公共基类中的内容
【2】菱形继承存在的问题
- 会发生二义性的问题(同一个变量或者函数,可以通过两种方法访问)
- 如果公共基类,过大,会造成汇集子类中的代码膨胀/冗余
#include <iostream>using namespace std;
class A
{
public:int a;//A(int a):a(a){cout << "A" << endl;}
};class B:public A
{
public:int c;//B(int a,int c):A(a),c(c){cout << "B" << endl;}
};class C:public A
{
public://C(int a):A(a){cout << "C" << endl;}
};class D:public C,public B
{
public://D(int a,int c):B(a,c),C(a),A(a){cout << "D" << endl;}
};int main()
{
D d1;
d1.B::a = 90; //二义性,还可以直接通过中间子类访问,直接访问B中的a成员//cout << d1.C::A::a << endl; //会发生二义性,因为访问A,但是有两条路径都访问到Areturn 0;
} 【3】虚继承(virtual)
虚继承指对公共基类的虚继承。
主要用于解决菱形继承问题,
采用虚继承后,公共基类中的内容,只会在汇集子类中存在一份,在汇集子类中,可以通过任意一条路径访问到公共基类中的成员
#include <iostream>using namespace std;
class A
{
public:int a;
};class B:virtual public A
{
public:int c;
};class C:virtual public A
{};class D:public B,public C
{};int main()
{
D d1;
d1.B::A::a = 90;
cout << d1.C::A::a << endl;return 0;
}
相关文章:
C++基础知识(六:继承)
首先我们应该知道C的三大特性就是封装、继承和多态。 此篇文章将详细的讲解继承的作用和使用方法。 继承 一个类,继承另一个已有的类,创建的过程 父类(基类)派生出子类(派生类)的过程 继承提高了代码的复用性 【1】继承的格式 class 类名:父类名 {}; 【…...
RM电控讲义【HAL库篇】(二)
8080并口模式是一种常见的计算机接口模式,主要用于LCD(液晶显示屏)模块。 在8080并口模式中,通信端口包括多种信号线,用于实现数据的读写和控制功能。主要的信号线包括: CS(片选信号ÿ…...
Mac安装Appium
一、环境依赖 一、JDK环境二、Android-SDK环境(android自动化)三、Homebrew环境四、Nodejs 安装cnpm 五、安装appium六、安装appium-doctor来确认安装环境是否完成七、安装相关依赖 二、重头大戏, 配置wda(WebDriverAgent&#x…...
数据库管理-第153期 Oracle Vector DB AI-05(20240221)
数据库管理153期 2024-02-21 数据库管理-第153期 Oracle Vector DB & AI-05(20240221)1 Oracle Vector的其他特性示例1:示例2 2 简单使用Oracle Vector环境创建包含Vector数据类型的表插入向量数据 总结 数据库管理-第153期 Oracle Vecto…...
通过傅里叶变换进行音频变声变调
文章目录 常见音频变声算法使用Wav库读写音频文件使用pitchShift算法进行音频变调主文件完整代码工程下载地址常见音频变声算法 在游戏或者一些特殊场景下为了提高娱乐性或者保护声音的特征,我们会对音频进行变声变调处理。常用的算法包括: 1.基于傅里叶变换的频域算法,该类…...
Opencv(C++)学习 ARM上引用opencv报相关头文件找不到
简单问题记录,C 与C互相引用时应该多注意类似问题。 问题描述:在项目中,建立了一个interface.h提供了一个C语言兼容的接口void work(),并在对应的interface.cpp中使用OpenCV完成相关处理实现。在PC端测试时,main.cpp成…...
中国服装行业ERP的现状与未来发展
随着全球数字化浪潮的兴起,中国服装行业也在不断探索数字化转型的路径,其中ERP(企业资源计划)系统作为管理和优化企业资源的重要工具,在服装行业中发挥着日益重要的作用。本文将探讨中国服装行业ERP的现状、作用&#…...
Unix与Linux区别
目录 历史和所有权 内核 发行版 开源性质 用户群体 命令行界面 历史和所有权 Unix: Unix是一个操作系统家族的名称,最早由贝尔实验室(Bell Labs)的肖像电机公司(AT&T)开发。最早的Unix版本是在19…...
惠尔顿 网络安全审计系统 任意文件读取漏洞复现
0x01 产品简介 惠尔顿网络安全审计产品致力于满足军工四证、军工保密室建设、国家涉密网络建设的审计要求,规范网络行为,满足国家的规范;支持1-3线路的internet接入、1-3对网桥;含强大的上网行为管理、审计、监控模块;…...
Chrome插件(二)—Hello World!
本小节将指导你从头到尾创建一个基本的Chrome插件,你可以认为是chrome插件开发的“hello world”! 以下详细描述了各个步骤: 第一步:设置开发环境 确保你拥有以下工具: 文本编辑器:如Visual Studio Cod…...
DBAPI如何使用数组类型参数
DBAPI如何使用数组类型参数 需求 根据多个id去查询学生信息 API创建 在基本信息标签,创建参数ids ,参数类型选择 Array<bigint> 在执行器标签,填写sql,使用in查询 select * from student where id in <foreach ope…...
博途PLC PID仿真(单容水箱液位高度控制含变积分变增益测试)
单容水箱和双荣水箱的微分方程和数值求解,可以参考下面文章链接: https://rxxw-control.blog.csdn.net/article/details/131139432https://rxxw-control.blog.csdn.net/article/details/131139432这篇博客我们利用欧拉求解器在PLC里完成单容水箱的数学建模。PLC也可以和MATL…...
第1集《灵峰宗论导读》
《灵峰宗论》导读。诸位法师,诸位同学,阿弥陀佛!(阿弥陀佛!) 学人很高兴,这次有一个殊胜的因缘来跟大家共同地学习《灵峰宗论》的课程。《灵峰宗论》是蕅益大师一生当中在佛法的修学心得。在蕅…...
nuxt CSS 存放到独立文件进行SEO优化
nuxt CSS 到独立文件 在Nuxt.js中将CSS样式从单个文件分离为多个独立的文件可以通过使用extract-text-webpack-plugin来完成。 首先,确保已经安装了该插件: npm install extract-text-webpack-plugin --save-dev然后,在项目根目录下创建一个…...
台式电脑电源功率越大越费电吗?装机选购多少W电源
要组装一台电脑,我们首先需要选择硬件。 硬件搭配最关键的一点就是CPU和主板的兼容性。 硬件、电源等之间的平衡都需要仔细考虑。 那么台式电脑电源多大功率合适呢? 下面分享组装电脑电源瓦数选购指南,教您正确选择合适的电源瓦数。 让我们来…...
《TCP/IP详解 卷一》第4章 地址解析协议ARP
目录 4.1 引言 4.2 一个例子 4.3 ARP缓存 4.4 ARP帧格式 4.5 ARP例子 4.6 ARP缓存超时 4.7 代理ARP 4.8 免费ARP和地址冲突检测 4.9 ARP命令 4.10 使用ARP设置嵌入式设备IPv4地址 4.11 与ARP相关攻击 4.12 总结 4.1 引言 地址解析: IPv4:AR…...
如何在pgAdmin中用替换的值更新jsonb列?
我有一个名为files的PostgreSQL表,其中包括一个名为formats的jsonb表。虽然有些行是[null],但其他行具有此结构的对象: {"thumbnail": {"ext": ".jpg","url": "https://some-url.com/image01.…...
冯诺依曼体系结构 计算机组成的金字塔
01 冯诺依曼体系结构:计算机组成的金字塔 学习计算机组成原理,到底是在学些什么呢?这个事儿,一两句话还真说不清楚。不过没关系,我们先从“装电脑”这个看起来没有什么技术含量的事情说起,来弄清楚计算机到…...
AWS安全组是什么?有什么用?
最近看到小伙伴在问,AWS安全组是什么?有什么用?今天我们大家就来简单聊聊,仅供参考哦! AWS安全组是什么?有什么用? 【回答】:AWS安全组是一种虚拟防火墙,用于控制进出…...
SSM项目集成Spring Security 4.X版本 之 加入DWZ,J-UI框架实现登录和主页菜单显示
目录 前言 一、加入DWZ J-UI框架 二、实现登录页面 三、实现主页面菜单显示 前言 大家好!写文章之前先列出几篇相关文章。本文内容也在其项目中接续实现。 一. SSM项目集成Spring Security 4.X版本(使用spring-security.xml 配置文件方式ÿ…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
Java数组Arrays操作全攻略
Arrays类的概述 Java中的Arrays类位于java.util包中,提供了一系列静态方法用于操作数组(如排序、搜索、填充、比较等)。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序(sort) 对数组进行升序…...
跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践
在电商行业蓬勃发展的当下,多平台运营已成为众多商家的必然选择。然而,不同电商平台在商品数据接口方面存在差异,导致商家在跨平台运营时面临诸多挑战,如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...
