当前位置: 首页 > news >正文

C++学习笔记(十二)------is_a关系(继承关系)

 

你好,这里是争做图书馆扫地僧的小白。

个人主页:争做图书馆扫地僧的小白_-CSDN博客

目标:希望通过学习技术,期待着改变世界。


 提示:以下是本篇文章正文内容,下面案例可供参考

文章目录

前言  

一、继承关系的语法形式

        (一)单继承的语法格式:

        (二)多继承的语法形式

         (三)单继承关系举例

二、继承关系的意义

三、继承关系的权限问题

四、单继承

        (一)单继承关系下的内存布局        

        1.举个例子,代码如下:

        2.图解如下:

(二)自动隐藏机制

(三)继承关系下的类型兼容规则

 五、多继承

        (一)多继承举例说明:

(二)多继承的内存布局

总结


前言  

        随着技术的革新,出现各种各样的编程语言,C++就是其中之一,作为最受欢迎的编程语言之一,C++带给开发者们最大的惊喜便是其强大的特性。一方面跟C兼容,可以直面系统底层API,SDK,另一方面提供了很多范式,足够的抽象能力,面向对象,操作符重载,模板等。

        之前的C++学习笔记(十一)------has_a和use_a关系-CSDN博客已经讲解了has_a和use_a关系,本篇将讲解最为重要的一种关系即is_a关系(继承关系)。


一、继承关系的语法形式

        (一)单继承的语法格式:

class 子类 : 继承权限 + 父类
{//继承即是子类继承了父类中的所有属性与方法(构造函数除外)
};

        (二)多继承的语法形式

class 子类 : 继承权限1,父类1,继承权限2,父类2,... 继承权限n,父类n
{//子类继承多个父类中的所有属性与方法。
}

        注意:继承关系中,子类并不继承父类中的构造函数。因为构造函数是特别的为本类域进行初始化的函数,并不会被继承。子类中要有子类的默认构造或自定义有参构造。

       多继承一般情况不使用,如果使用多用于集成多个抽象类,原因见下文的多继承部分。

         (三)单继承关系举例

#include <iostream>
using namespace std;
class Car
{
public:int price;
public:void run(){cout << "汽车在行驶" << endl;}
};
class BYD : public Car
{
public:void uniqueEmblem(){cout << "有着中国特色的车标" << endl;}
};
int main()
{BYD byd;byd.run();byd.price;byd.uniqueEmblem();return 0;
}

二、继承关系的意义

        继承关系的意义是:代码复用性与高拓展性。

        使用继承关系的步骤:首先把这类的事件抽象出来一些共有的属性与特征,把它们定义为父类。再用这个父类,对具有不同特点的子类进行派生,就可以派生出各种不同的子类。这样的子类有着公有的属性,还有着各自独特的性质。

三、继承关系的权限问题

#include <iostream>
using namespace std;class Car
{
public:int price;
public:void run(){cout << "汽车在行驶" << endl;}
};class BYD : private Car
{
public:void uniqueEmblem(){cout << "有着中国特色的车标" << endl;}
};int main()
{BYD byd;byd.run();byd.price;byd.uniqueEmblem();return 0;
}

         继承关系图如下所示,如图所示当子类继承父类时,可以理解为将父类整体打包,将其作为一整个属性赋给子类。

        注意:每一种继承关系对父类各种权限的属性的访问也是有区别的。当public继承时,对父类中private权限的属性不管是在子类的类外还是类内都没有访问权限;对父类中protected权限的属性在子类的类内有访问权限且为protected访问权限,在子类类外没有访问权限;对父类中public属性的属性不管是在子类类内还是类外都是public访问权限。其余两种不在采用文字形式进行描述,详细的直观的描述见下面的表格。

四、单继承

        (一)单继承关系下的内存布局        

        子类对象被构造时,先构造父类,然后再调用子类的构造完成对子类类域中拓展的属性进行初始化,此时,子类的对象具有具体初始值。析构的时候先析构子类,然后在析构父类。

        注意的是子类析构被执行,父类析构也一定被析构。原因是内存绑定

        1.举个例子,代码如下:

#include <iostream>
using namespace std;
class Car
{
private:int price;
public:void run(){cout << "汽车在行驶" << endl;}Car(){cout << "Car父类的构造" << endl;}~Car(){cout << "Car父类的析构" << endl;}
};
class BYD : private Car
{
public:BYD(){cout << "BYD子类的构造"  << endl;}~BYD(){cout << "BYD子类的析构" << endl;}
};int main()
{BYD byd;return 0;
}

        2.图解如下:

(二)自动隐藏机制

        当子类中有与父类同名属性或函数时,父类中的同名属性或行为将自动隐藏在自己的父类的类域之中,如果想访问父类类域之中的属性或行为,就使用域名::访问。

        举个例子,代码如下:

#include <iostream>
#include <unistd.h>
using namespace std;
class Car
{
public:int price = 10000;
public:void run(){cout << "车子正在行驶之中" << endl;}Car(){cout << "Car父类的构造" << endl;}~Car(){cout << "Car父类的析构" << endl;}
};class BYD : public Car
{
public:int weight = 20000;
public:void run(){cout << "BYD高速行驶" << endl;}BYD(){cout << "BYD子类的构造" << endl;}~BYD(){cout << "BYD子类的析构" << endl;}
};
int main()
{BYD byd;cout << byd.Car::price << endl;byd.run();byd.Car::run();return 0;
}

(三)继承关系下的类型兼容规则

        在之前我们学到当使用指针的时候,要保证等号前后的指针类型要相同才可以,在继承中不然。继承关系中父类指针或者引用可以安全的指向或者引用子类类型的对象,但是子类指针或者引用并不能指向或者引用父类类型的对象。

        需要注意的是使用父类指针在释放资源时,注意要强转成子类指针才可以完全释放,不然会造成资源的泄露。

        还需要注意的是当父类中只有有参构造的时候,子类的构造函数处应该进行初始化列表的操作,指定父类的有参构造对其进行初始化操作,否则会报错。

        举个例子,代码如下:

#include <iostream>
#include <unistd.h>
using namespace std;
class Car
{
public:int price = 10000;
public:void run(){cout << "汽车在行驶" << endl;}Car(int price){cout << "Car父类的构造" << endl;}~Car(){cout << "Car父类的析构" << endl;}
};
class BYD : public Car
{
public:int price = 20000;
public:void run(){cout << "BYD高速行驶" << endl;}BYD():Car(1)  {cout << "BYD子类的构造" << endl;}~BYD(){cout << "BYD子类的析构" << endl;}
};
int main()
{//栈上定义对象BYD byd;Car* c = &byd;   //父类属性的指针可以安全的指向子类属性c->run();        //调用父类中子类和父类公有的run方法cout << c->price << endl;  //10000Car& ref_c = byd;  //父类属性的引用可以安全的指向子类属性ref_c.run();        //调用父类中子类和父类公有的run方法cout << ref_c.price << endl;  //10000//用堆上的对象:Car* ptr_c = new BYD();ptr_c->run();delete (BYD*)ptr_c;  //释放指针时,需要进行强转,否则只采用delete ptr_c,只会析构父类,而子类指向的堆上资源并没有被回收return 0;
}

 五、多继承

        在多继承时,虽然多继承可以大在提高代码的复用性,但是会造成代码冗余,当多个父类中有同名函数或属性时,在访问时候会出现二义性的问题。

        需要注意使用类域::访问的方式进行指定访问,但是这样给程序设计带来很多不便,所以多继承在开发时尽量避免。如果一定要使用多继承时,推荐使用多继承多个抽象类,因为抽象类一般都没有具体的属性,只有纯虚函数。

        (一)多继承举例说明:

#include <iostream>
using namespace std;
class Phone
{
public:int power;
public:void sendMessage(){cout << "发消息" << endl;}
};
class Pad
{
public:int power;
public:void playGame(){cout << "玩游戏" << endl;}
};
class Computer : public Phone, public Pad
{};
int main()
{Computer computer;computer.sendMessage();computer.playGame();cout << computer.Phone::power << endl;  cout << sizeof(Computer) << endl;return 0;
}

(二)多继承的内存布局

        注意:当上述例子中定义Phone *p = &computer 和 Pad *p1 = &computer 这两个指针指向的地址空间是否一致?

        答案是不一致的,当使用父类指针指向子类时,在继承中父类指针永远指向的是自己类中的起始地址。

        当然多继承也符合继承关系下的类型兼容规则。


总结

        以上就是今天要讲的内容,本文将is_a关系(继承关系)进行了详细的介绍,分成了单继承和多继承,并对继承中权限问题和内存布局进行了详细的介绍,当然多继承中还存在着一种特殊的构造形式即为菱形继承,这部分将留作下篇笔记进行撰写。

相关文章:

C++学习笔记(十二)------is_a关系(继承关系)

你好&#xff0c;这里是争做图书馆扫地僧的小白。 个人主页&#xff1a;争做图书馆扫地僧的小白_-CSDN博客 目标&#xff1a;希望通过学习技术&#xff0c;期待着改变世界。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 文章目录 前言 一、继承关系…...

DC电源模块的设计与制造技术创新

BOSHIDA DC电源模块的设计与制造技术创新 DC电源模块的设计与制造技术创新主要涉及以下几个方面&#xff1a; 1. 高效率设计&#xff1a;传统的DC电源模块存在能量转换损耗较大的问题&#xff0c;技术创新可通过采用高效率的电路拓扑结构、使用高性能的功率开关器件和优化控制…...

Sketch for Mac:实现你的创意绘图梦想的矢量绘图软件

随着数字时代的到来&#xff0c;矢量绘图软件成为了广告设计、插画创作和UI设计等领域中必不可少的工具。在众多矢量绘图软件中&#xff0c;Sketch for Mac&#xff08;矢量绘图软件&#xff09;以其强大的功能和简洁的界面脱颖而出&#xff0c;成为了众多设计师的首选。 Sket…...

ReactNative0.73发布,架构升级与更好的调试体验

这次更新包含了多种提升开发体验的改进&#xff0c;包括&#xff1a; 更流畅的调试体验: 通过 Hermes 引擎调试支持、控制台日志历史记录和实验性调试器&#xff0c;让调试过程更加高效顺畅。稳定的符号链接支持: 简化您的开发工作流程&#xff0c;轻松将文件或目录链接到其他…...

SVN忽略文件的两种方式

当使用版本管理工具时&#xff0c;提交到代码库的文档我们不希望存在把一些临时文件也推送到仓库中&#xff0c;这样就需要用到忽略文件。SVN的忽略相比于GIT稍显麻烦&#xff0c;GIT只需要在.gitignore添加忽略规则即可。而SVN有两种忽略方式&#xff0c;一个是全局设置&#…...

手写VUE后台管理系统10 - 封装Axios实现异常统一处理

目录 前后端交互约定安装创建Axios实例拦截器封装请求方法业务异常处理 axios 是一个易用、简洁且高效的http库 axios 中文文档&#xff1a;http://www.axios-js.com/zh-cn/docs/ 前后端交互约定 在本项目中&#xff0c;前后端交互统一使用 application/json;charsetUTF-8 的请…...

JavaScript装饰者模式

JavaScript装饰者模式 1 什么是装饰者模式2 模拟装饰者模式3 JavaScript的装饰者4 装饰函数5 AOP装饰函数6 示例&#xff1a;数据统计上报 1 什么是装饰者模式 在程序开发中&#xff0c;许多时候都我们并不希望某个类天生就非常庞大&#xff0c;一次性包含许多职责。那么我们就…...

C++学习笔记01

01.C概述&#xff08;了解&#xff09; c语言在c语言的基础上添加了面向对象编程和泛型编程的支持。 02.第一个程序helloworld&#xff08;掌握&#xff09; #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std;//标准命名空间int main() {//co…...

【UE5】初识MetaHuman 创建虚拟角色

步骤 在UE5工程中启用“Quixel Bridge”插件 打开“Quixel Bridge” 点击“MetaHumans-》MetaHuman Presets UE5” 点击“START MHC” 在弹出的网页中选择一个虚幻引擎版本&#xff0c;然后点击“启动 MetaHuman Creator” 等待一段时间后&#xff0c;在如下页面点击选择一个人…...

物流实时数仓:数仓搭建(DWD)一

系列文章目录 物流实时数仓&#xff1a;采集通道搭建 物流实时数仓&#xff1a;数仓搭建 物流实时数仓&#xff1a;数仓搭建&#xff08;DIM&#xff09; 物流实时数仓&#xff1a;数仓搭建&#xff08;DWD&#xff09;一 文章目录 系列文章目录前言一、文件编写1.目录创建2.b…...

MATLAB安装

亲自验证有效&#xff0c;多谢这位网友的分享&#xff1a; https://blog.csdn.net/xiajinbiaolove/article/details/88907232...

C语言——预处理详解(#define用法+注意事项)

#define 语法规定 #define定义标识符 语法: #define name stuff #define例子 #include<stdio.h> #define A 100 #define STR "abc" #define FOR for(;;)int main() {printf("%d\n", A);printf("%s\n", STR);FOR;return 0; } 运行结果…...

Linux(23):Linux 核心编译与管理

编译前的任务&#xff1a;认识核心与取得核心原始码 Linux 其实指的是核心。这个【核心(kernel)】是整个操作系统的最底层&#xff0c;他负责了整个硬件的驱动&#xff0c;以及提供各种系统所需的核心功能&#xff0c;包括防火墙机制、是否支持 LVM 或 Quota 等文件系统等等&a…...

Oracle RAC环境下redo log 文件的扩容

环境&#xff1a; 有一个2节点RAC每一个节点2个logfile group每一个group含2个member每一个member的大小为200M 目标&#xff1a;将每一个member的大小有200M扩充到1G。 先来看下redo log的配置&#xff1a; SQL> select * from v$log;GROUP# THREAD# SEQUENCE# …...

Java入门学习笔记一

一、Java语言环境搭建 1、JAVA语言的跨平台原理 1.1、什么是跨平台性&#xff1f; 跨平台就是说&#xff0c;同一个软件可以在不同的操作系统&#xff08;例如&#xff1a;Windows、Linux、mad&#xff09;上执行&#xff0c;而不需要对软件做任务处理。即通过Java语言编写的…...

分布式块存储 ZBS 的自主研发之旅|元数据管理

重点内容 元数据管理十分重要&#xff0c;犹如整个存储系统的“大黄页”&#xff0c;如果元数据操作出现性能瓶颈&#xff0c;将严重影响存储系统的整体性能。如何提升元数据处理速度与高可用是元数据管理的挑战之一。SmartX 分布式存储 ZBS 采用 Log Replication 的机制&…...

六大设计原则

六大设计原则 1、单一职责原则 一个类或者模块只负责完成一个职责或者功能。 2、开放封闭原则 规定软件中的对象、类、模块和函数对扩展应该是开放的&#xff0c;对于修改应该是封闭的。用抽象定义结构&#xff0c;用具体实现扩展细节。 3、里氏替换原则 如果S是T的子类型…...

dockerfile创建镜像 lNMP+wordpress

dockerfile创建镜像 lNMPwordpress nginx dockernginx mysql dockermysql php dockerphp nginx vim nginx.conf vim Dockerfile docker network create --subnet172.17.0.0/16 --opt "com.docker.network.bridge.name""docker1" mynetwork docker buil…...

深入理解——快速排序

目录 &#x1f4a1;基本思想 &#x1f4a1;基本框架 &#x1f4a1;分割方法 ⭐Hoare版本 ⭐挖坑法 ⭐前后指针法 &#x1f4a1;优化方法 ⭐三数取中法 ⭐小区间内使用插入排序 &#x1f4a1;非递归实现快速排序 &#x1f4a1;性能分析 &#x1f4a1;基本思想 任取待排…...

【代码随想录】算法训练计划50

dp 1、123. 买卖股票的最佳时机 III 题目&#xff1a; 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再次购…...

【数据分享】2019-2023年我国区县逐年二手房房价数据(Excel/Shp格式)

房价是一个区域发展程度的重要体现&#xff0c;一个区域的房价越高通常代表这个区域越发达&#xff0c;对于人口的吸引力越大&#xff01;因此&#xff0c;房价数据是我们在各项城市研究中都非常常用的数据&#xff01;之前我们分享了2019—2023年我国区县逐月的二手房房价数据…...

Redis设计与实现之整数集合

目录 一、内存映射数据结构 二、整数集合 1、整数集合的应用 2、数据结构和主要操作 3、intset运行实例 创建新intset 添加新元素到 intset 添加新元素到 intset&#xff08;不需要升级&#xff09; 添加新元素到 intset (需要升级) 4、升级 升级实例 5、关于升级 …...

[Kubernetes]2. k8s集群中部署基于nodejs golang的项目以及Pod、Deployment详解

一. 创建k8s部署的镜像 1.部署nodejs项目 (1).上传nodejs项目到节点node1 (2).压缩nodejs项目 (3).构建nodejsDockerfile 1).创建nodejsDockerfile 具体可参考:[Docker]十.Docker Swarm讲解,在/root下创建nodejsDockerfile,具体代码如下: FROM node #把压缩文件COPY到镜像的…...

讯飞星火大模型api调用

讯飞星火大模型&#xff0c;通过websocket方式通信传递协议要求的报文&#xff0c;然后将流式返回的报文拼接为完整的响应内容&#xff0c;status2时是最后一条消息。因为是websocket方式所以是异步响应的&#xff0c;如果想要同步需要使用CountDownLatch控制下线程等待最后一条…...

TCP与UDP:网络世界中的“顺丰快递”与“广播电台”

随着互联网的普及&#xff0c;我们每天都在与网络打交道。而在这背后&#xff0c;数据的传输离不开TCP和UDP这两种传输协议。它们就像网络世界中的“顺丰快递”和“广播电台”&#xff0c;各自有着不同的工作方式和特点。让我们一起来了解一下它们吧&#xff01; 一、TCP&…...

升级Xcode15,iOS17后问题解决

1、Could not build module ‘WebKit’ 报错 解决方案&#xff1a; 编辑文件 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.0.sdk/System/Library/Frameworks/WebKit.framework/Headers/WKWebsiteDataStore.h 将里面…...

RabbitMQ搭建集群环境、配置镜像集群、负载均衡

RabbitMQ集群搭建 Linux安装RabbitMQ下载安装基本操作命令开启管理界面及配置 RabbitMQ集群搭建确定rabbitmq安装目录启动第一个节点启动第二个节点停止命令创建集群查看集群集群管理 RabbitMQ镜像集群配置启用HA策略创建一个镜像队列测试镜像队列 负载均衡-HAProxy安装HAProxy…...

leetcode:457. 环形数组是否存在循环

环形数组是否存在循环 存在一个不含 0 的 环形 数组 nums &#xff0c;每个 nums[i] 都表示位于下标 i 的角色应该向前或向后移动的下标个数&#xff1a; 如果 nums[i] 是正数&#xff0c;向前&#xff08;下标递增方向&#xff09;移动 |nums[i]| 步 如果 nums[i] 是负数&…...

Kafka集成springboot

安装kafka&#xff0c;直接到官网下载bin文件&#xff0c;本文使用windows进行使用kafka。 下载之后&#xff0c;第一步&#xff0c;启动zookeeper&#xff1a; zookeeper-server-start.bat ..\..\config\zookeeper.properties 第二步&#xff0c;启动kafka&#xff1a; kafka…...

Unity中实现ShaderToy卡通火(移植篇)

文章目录 前言一、准备好我们的后处理基础脚本1、C#&#xff1a;2、Shader&#xff1a; 二、开始逐语句对ShaderToy进行转化1、首先&#xff0c;找到我们的主函数 mainImage2、其余的方法全部都是在 mainImage 函数中调用的方法3、替换后的代码(已经没报错了&#xff0c;但是效…...

北京网站制作郑州/seo关键词推广多少钱

导语&#xff1a;考试周到来&#xff0c;大一新生如何备考&#xff0c;才能保证期末考试不挂科呢&#xff1f;无论是中学生还是大学生&#xff0c;每学期末&#xff0c;期末考试都是绕不过的话题。只不过这两的难度跟影响不同。中学时代的期末考试比较难&#xff0c;上课不认真…...

免费下载建设银行官方网站/武汉网站seo服务

最近一直再跟同一个项目UEEEU&#xff0c;干了很多事&#xff0c;锻炼自然也很多&#xff0c;这阵子也是从早到晚的忙活&#xff0c;身体似乎都不知疲惫的说&#xff0c;其实忙着也好&#xff0c;有钱有经验嘛&#xff0c;多踏实哈。这一年来又变了很多&#xff0c;进步很多&am…...

蒙icp备 网站建设/西安快速排名优化

背景&#xff1a; 虹软的人脸识别还是不错的&#xff0c;在官方注册一个账号&#xff0c;成为开发者&#xff0c;下载SDK的jar包&#xff0c;在开发者中心&#xff0c;找一个demo就可以开始做了&#xff0c;安装里边的逻辑&#xff0c;先看理解代码&#xff0c;然后就可以控制代…...

wordpress 网店/软件培训机构排名

增删节点 数据迁移一、所有事情开始之前&#xff0c;先要备份好cloudera manager的数据库&#xff0c;以及hadoop集群中的一些组件带的数据库。这里保存了很多元数据&#xff0c;像hive这种丢了很麻烦的。二、如果需要换nameNode的存储目录1、备份nameNode原始数据cp -r /ddhom…...

wordpress优秀中文主题/怎样做一个网页

直播概要 直播演讲主题&#xff1a;远程办公有点上头&#xff1f;解锁云上应用现代化的奥秘 直播时间&#xff1a;5月31日19:00 直播地址&#xff1a;微信视频号、哔哩哔哩、知乎搜索亚马逊云科技&#xff0c;三大平台同步直播。 话题介绍 在新挑战频发的动荡变革时期&…...

个人可做网站需要什么材料/googleplay官方下载

有时候当我们拿到web页内容时会发现我们需要的内容显示过大&#xff0c;而我们因为项目需求不能让其滑动这时我们该怎么办呢&#xff0c; - (void)webViewDidFinishLoad:(UIWebView *)webView {[webView stringByEvaluatingJavaScriptFromString:"document.body.style.zoo…...