C++继承详解
继承
- 1. 继承的概念和定义
- 1.1 继承的概念
- 1.2 继承的定义
- 1.2.1 继承的格式
- 1.2.2 继承方式
- 2. 基类和派生类对象的赋值转换
- 3.继承中的作用域
- 4. 继承中的默认成员函数
- 5. 继承和友元
- 6. 继承和静态成员
1. 继承的概念和定义
1.1 继承的概念
继承是面向对象编程中的一个重要概念,它允许一个类(称为子类/派生类)继承另一个类(称为父类/基类)的属性和方法。子类可以重用父类的代码,并且可以添加自己的新属性和方法,或者重写父类的方法以满足自己的特定需求。
继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。

1.2 继承的定义
1.2.1 继承的格式
class 派生类 : 继承方式 基类
class Person
{
protected:string _name;int _age;
};class Student : public Person
{
protected:int _stuid;
};
1.2.2 继承方式
继承方式的关键字和访问修饰权限符是一样的,有三种:public、protected、private。相信大家都很熟悉。那这三种继承方式会有什么不同呢?情况有很多,但大家只要记住一句话,取权限小的那个,按照权限排序是public > protected > private。比如为public继承方式,我们用pubilc和基类的成员变量、成员函数的访问修饰权限符作比较取小的那个作为派生类继承过来的该成员变量或成员函数的访问权限符号。

总结:
- 基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。
- 在继承之前是没有protected这个关键字出现的。基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。
- 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。
- 实际运用中基本使用public继承方式。
2. 基类和派生类对象的赋值转换
先说几个结论:
- 派生类对象可以赋值给基类的对象、基类的指针、基类的引用。这时候会发生对象切片(object slicing)。这意味着只有基类部分的成员变量和方法会被复制到基类对象中,而派生类特有的成员变量和方法将被丢失。
- 基类的对象不能赋值给派生类。
- 类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针是指向派生类对象时才是安全的。这里基类如果是多态类型,可以使用RTTI(RunTime Type Information)的dynamic_cast 来进行识别后进行安全转换。
代码演示:
class Person
{
protected:string _name = "张三";int _age = 18;
};
class Student : public Person
{
protected:int _stuid = 10086;
};
int main()
{Student s;Person p;p = s;Person* p1 = new Student;Person& p2 = s;return 0;
}

3.继承中的作用域
我们思考一个问题?如果父类和子类的成员对象名一样会发生什么?
class A
{protected:int num = 10;
};
class B : public A
{
public:void fun(){cout << num << endl;}
protected:int num = 20;
};
int main()
{B b;b.fun();
}

从结果可以看出,我们打印出来的是B中的num,那么A中的num去哪了?是被重新赋值了吗?答案是被隐藏了,也叫重定向,它在A的作用域中,可以通过::来访问。
class A
{protected:int num = 10;
};
class B : public A
{
public:void fun(){cout << "B的num:" << num << endl;cout << "A的num:" << A::num << endl;}
protected:int num = 20;
};
int main()
{B b;b.fun();
}

函数也是同理,只需要函数名称相同,基类的函数就会被隐藏起来。
class A
{
public:int fun(int a, int b){cout << "我是A的fun()" << endl;return a + b;}
protected:int num = 10;
};
class B : public A
{
public:void fun(){cout << "我是B的fun()" << endl;}
protected:int num = 20;
};
int main()
{B b;b.fun();
}

总结:
- 在继承体系中基类和派生类都有独立的作用域。
- 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏, 也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)
- 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。
- 注意在实际中在继承体系里面最好不要定义同名的成员
4. 继承中的默认成员函数
我们之前将如果我们不写,编译器会默认生成6个成员函数。我们这里讨论前4个函数在继承中的行为。
- 派生类的构造函数必须调用基类的构造函数来初始化基类那部分的成员变量。如果基类没有默认构造,那我们必须在派生类的初始化列表显示调用构造函数。(必须先构造父类再构造子类)
- 派生类的拷贝构造函数必须调用基类的拷贝构造函数来完成基类的初始化。
- 派生类的赋值必须要调用子类的赋值
- 必须先析构派生类然后再析构基类,因为如果先析构基类,会造成派生类如果使用基类的成员会造成野指针问题。
- 注:虽然派生类的析构函数名和基类的析构函数名不同,但由于后面的多态重写部分,析构函数名会被编译器处理destrutor()。所以基类析构函数不加virtual的情况下,派生类析构函数和父类析构函数构成隐藏关系。
- 派生类的析构函数不用显示调用基类的析构函数,编译器会在派生类析构以后,再自动调用基类的析构函数,保证了第4点。
class Person
{
public:Person(string name,int age):_name(name),_age(age){cout << "Person(string name,int age)" << endl;}Person(const Person& l){_name = l._name;cout << "Person(const Person& l)" << endl;}Person& operator==(const Person& l){cout << "Person& operator==(const Person& l)" << endl;if (this != &l){_name = l._name;}return *this;}~Person(){cout << "~Person()" << endl;}
protected:string _name;int _age;
};class Student : public Person
{
public:Student(string name, int age, int stid):Person(name, age), _stid(stid){cout << "Student(string name, int age, int stid)" << endl;}Student(const Student& s):Person(s){cout << "Student(const Student& s)" << endl;_stid = s._stid;}Student& operator==(const Student& s){cout << "Student& operator==(const Student& s)" << endl;Person::operator==(s);if (this != &s){_stid = s._stid;}}~Student(){cout << "~Student()" << endl;}
protected:int _stid;
};int main()
{Student s("张三",20,10086);Student s1(s);Student s2 = s1;return 0;
}

5. 继承和友元
爸爸的朋友并不是你的朋友,所以友元关系不能继承。故友元函数不能访问子类的私有和保护成员。
6. 继承和静态成员
基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子 类,都只有一个static成员实例。
相关文章:
C++继承详解
继承 1. 继承的概念和定义1.1 继承的概念1.2 继承的定义1.2.1 继承的格式1.2.2 继承方式 2. 基类和派生类对象的赋值转换3.继承中的作用域4. 继承中的默认成员函数5. 继承和友元6. 继承和静态成员 1. 继承的概念和定义 1.1 继承的概念 继承是面向对象编程中的一个重要概念&…...
docker数据卷的使用
文章目录 1、数据卷产生背景2、数据卷的使用2.1、创建数据卷2.2、挂载数据卷2.3、共享数据卷2.4、删除数据卷2.5、备份和迁移数据卷 总结 1、数据卷产生背景 Docker的镜像是由一系列的只读层组合而来,当启动一个容器时,Docker加载镜像的所有只读层&…...
2024獬豸杯完整Writeup
文章目录 手机手机基本信息- 1、IOS手机备份包是什么时候开始备份的。(标准格式:2024-01-20.12:12:12)手机基本信息- 2、请分析,该手机共下载了几款即时通讯工具。(标准格式:阿拉伯数字)手机基本信息- 3、手…...
Vue学习笔记之应用创建和基础知识
1、安装方式 CDN方式安装: <script src"https://unpkg.com/vue3/dist/vue.global.js"></script> 2、创建应用 使用Vue内置对象创建一个应用,基本代码结构如下: <script src"https://unpkg.com/vue3/dist/…...
CSS3基础知识总结
目录 一、CSS3 边框 1.border-radius:圆角边框 2.box-shadow:添加阴影 3.border-image:图片边框 二、CSS3 渐变 1.线性渐变(Linear Gradients) a.由上到下(默认) b.从左到右 c.对角 d.使用角度 2.径向渐变(…...
80.网游逆向分析与插件开发-背包的获取-自动化助手显示物品数据1
内容参考于:易道云信息技术研究院VIP课 上一个内容:升级Notice类获得背包基址-CSDN博客 码云地址(ui显示角色数据 分支):https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号:3be017de38c50653b…...
Python第三方扩展库NumPy
Python第三方扩展库NumPy NumPy(Numerical Python,注意使用时全部小写 numpy) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。 在Windows平台上安装numpy,可在cmd命令…...
Dockerfile简介和基础实践
文章目录 1、Dockerfile简介1.1、Dockerfile解决的问题1.2、docker build 构建流程1.3、关键字介绍 2、Dockerfile 实践2.1、基本语法实践 --- golang2.1.1 问题检查 2.2、基本语法实践 --- gcc 总结 1、Dockerfile简介 Dockerfile是一个创建镜像所有命令的文本文件, 包含了一…...
3分钟 docker搭建 帕鲁服务器
1. 安装docker 1.安装依赖环境 yum -y install yum-utils device-mapper-persistent-data lvm22.设置镜像源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo3.安装docker 3.1 yum makecache fast yum install docker-ce …...
[BUUCTF 2018]Online Tool(特详解)
这段代码块检查请求中是否设置了HTTP_X_FORWARDED_FOR头部。如果设置了,它将REMOTE_ADDR设置为HTTP_X_FORWARDED_FOR的值。这通常用于处理Web服务器位于代理后面的情况。 如果URL中未设置host参数,它使用highlight_file(__FILE__);来显示PHP文件的源代码…...
Qt Design Studio+Pyside项目
Qt Design Studio设计出的项目结构有多个层级的目录,我们直接用类似Qt Creator工具的方式加载main.qml文件时会报错提示module "content" is not installed,将content加入importPath后还是报同样的错误。 Qt Design Studio生成的文件包含了.qm…...
软件门槛之算法
软件门槛之算法 1.背景2.算法定义3.特征4.基本要素5.常用设计模式6.常用实现方法7.复杂度时间复杂度空间复杂度8.分类9.算法常用的一些工具10.算法的检验标准1.背景 一入行业深似海 再回首已是白发生! 工作这么多年了,感觉算法是比较难搞的。 写代码最重要的可能是框架和算法…...
第八篇【传奇开心果系列】beeware的toga开发移动应用示例:实现消消乐安卓手机小游戏
传奇开心果博文系列 系列博文目录beeware的toga开发移动应用示例系列博文目录一、项目目标二、安装依赖三、初步实现四、扩展思路五、实现游戏逻辑示例代码六、实现界面设计示例代码七、实现增加关卡和难度示例代码八、实现存档和排行榜示例代码九、实现添加特殊方块和道具示例…...
【MySQL】MySQL内置函数--日期函数/字符串函数/数学函数/其他相关函数
文章目录 1.日期函数2.字符串函数3.数学函数4.其它函数 1.日期函数 MySQL中内置了一下函数: 函数名称描述current_date()当前日期current_time()当前时间current_timestamp()当前时间戳date(datetime)返回datetime参数的日期部分date_add(date,interval d_value_t…...
应急响应红蓝工程师白帽子取证Linux和windows入侵排查还原攻击痕迹,追溯攻击者,以及各种木马和病毒以及恶意脚本文件排查和清除
应急响应红蓝工程师白帽子取证Linux入侵排查还原攻击痕迹,追溯攻击者,以及各种木马和病毒以及恶意脚本文件排查和清除。 一般服务器被入侵的迹象,包括但不局限于:由内向外发送大量数据包(DDOS肉鸡)、服务器资源被耗尽(挖矿程序)、不正常的端口连接(反向shell等)、服务…...
vue项目使用element-plus
介绍 1.element Plus 是一套基于 Vue.js 的组件库,是对饿了么团队的 Element UI 组件库的升级版本。Element Plus 的目标是提供一套更为现代、更好用的 Vue.js UI 组件。 导入 1.1 执行命令: npm install element-plus --save 1.2 在main.js中做如下配置import E…...
Fastbee物联网项目新手快速入门
一,前提条件 后端环境准备如下: 正式环境推荐硬件资源最低要求4c8G,硬盘40G。JDK 1.8.0_2xx (需要小版本号大于200) 。Maven3.6.3。(IDEA启动时使用IDEA默认自带的版本即可)。 启动fastbee之前,请先确定…...
Linux 网络流量相关工具
本文聚焦于网络流量的查看、端口占用查看。至于网络设备的管理和配置,因为太过复杂且不同发行版有较大差异,这里就不赘述,后面看情况再写。 需要注意的是,这里列出的每一个工具都有丰富的功能,流量/端口信息查看只是其…...
KMP算法关于next数组详解
j1234567abcabcdnext[j]0111234 要求j7的时候,next数组为多少,j7的时候,就是看i6的时候前缀和后缀的关系(因为求7的时候,和7没有关系,和7的前面有关系) 当i6的时候,j3,…...
【Docker】数据持久化 挂载
Docker的镜像是只读的,但是容器是可写的,我们可以将数据写入到容器,不过一旦容器删除数据将会丢 失,那么有什么办法能将数据进行持久化存储呢? ——在宿主机上开辟一块地方,存储内容和docker容器的存储内…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
