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关系(继承关系)进行了详细的介绍,分成了单继承和多继承,并对继承中权限问题和内存布局进行了详细的介绍,当然多继承中还存在着一种特殊的构造形式即为菱形继承,这部分将留作下篇笔记进行撰写。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/231225.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pipelined-ADC设计一:序言

现在是2023年12月18日&#xff0c;准备开新帖&#xff0c;设计一个 流水线型 模数转换器&#xff08; Pipelined-ADC &#xff09;。记录帖&#xff0c;后续会放在咸鱼。同步记录&#xff0c;谨防盗用。 初定指标&#xff1a;12位50Mhz&#xff0c;采用2.5bit每级结构&#xff…

使用DTS将自建MySQL迁移至PolarDB MySQL引擎,探索DTS全量数据校验

1. 领取免费的ECS和PolarDB资源 一旦您注册了阿里云账号并填写了您的账号和支付信息&#xff0c;您就可以申请免费试用我们的产品&#xff08;如ECS、PolarDB、RDS等服务&#xff09;。 1.1. 申请 ECS 免费试用 1. 在 阿里云免费试用中心&#xff0c;找到ECS&#xff0c;单击…

可视化 | 基于CBDB的唐代历史人物分析

文章目录 &#x1f4da;人口统计&#x1f407;唐朝历年人数统计&#x1f407;唐朝人口金字塔&#x1f407;唐朝历年出生死亡人数统计&#x1f407;唐朝人口分布&#x1f407;享年数据分布 &#x1f4da;唐朝人口迁徙&#x1f407;人口迁徙&#x1f407;生卒地变迁 &#x1f4da…

IDEA代码补全不能导入某个类了

问题 今天写单元测试时&#xff0c;突然发现idea自动补全代码时不能自动导入类了&#xff0c; 比如在编辑器中输入Test&#xff0c;正常情况下通过快捷键atl/智能补全提示后可以自动生成导入import org.junit.Test &#xff0c;但是现在不行了。 解决办法 由于在导入Test时不小…

【JavaWeb学习笔记】11 - WEB工程路径专题

一、工程路径问题 1.引入该问题 通过这几个去访问很麻烦 二、工程路径解决方案 1.相对路径 1.说明:使用相对路径来解决&#xff0c;一 个非常重要的规则:页面所有的相对路径&#xff0c;在默认情况下&#xff0c;都会参考当前浏览器地址栏的路径http:/ /ip:port/工程名/来进…

Go集成elasticsearch8极简demo,光速入门

Go集成elasticsearch8极简demo,光速入门 配置go环境创件go mod工程代码实现配置go环境 编辑器添加goproxy GO111MODULE=on;GOPROXY=https://mirrors.wps.cn/go/,https://goproxy.cn,direct;GOSUMDB=off创件go mod工程 mkdir demo cd demo go mod init demo代码实现 在demo…

JMESPath语言

JMESPath&#xff08;JSON Matching Expression Path&#xff09; 一种查询语言。 主要用于从JSON文档中检索和过滤数据。 通过写表达式提取和处理JSON数据&#xff0c;而无需编写复杂的代码。 功能&#xff1a;数据提取、过滤、转换、排序。 场景&#xff1a;处理API响应…

CentOS7安装Docker及添加阿里云镜像加速详细教程

Docker官方安装教程网站&#xff1a;Install Docker Engine on CentOS | Docker Docs 具体流程如下&#xff1a; 1.确定你是CentOS7及以上版本 cat /etc/redhat-release 2.yum安装gcc相关 yum -y install gcc yum -y install gcc-c 3.安装需要的软件包 3.1安装docker引擎…

MetaSploit工具的使用

在命令行输入&#xff1a;msfconsole 启动msf msfconsole 另外的方式 msfdb init msfdb run 查看数据库连接状态 db_status 扫描端口并存储 db_nmap 查看扫描到的数据信息 services MSF常用的模式和命令 搜索模块 search 模块名字 使用模块 use 编号 查看模块使用 sho…

对偶问题笔记(1)

目录 1 从 Lagrange 函数引入对偶问题2. 强对偶性与 KKT 条件3. 对偶性的鞍点特征 1 从 Lagrange 函数引入对偶问题 考虑如下优化问题 { min ⁡ f 0 ( x ) s . t f i ( x ) ≤ 0 , i 1 , ⋯ , p , h j ( x ) 0 , j 1 , ⋯ , q , x ∈ Ω , \begin{align} \begin{cases}\min…

在linux上基于shell自动部署Java项目

一&#xff0c;安装git yum list git 列出git安装包 yum install git 在线安装git 使用 git -varsion 查看是否安装成功 安装成功 二&#xff0c; Git克隆代码 git clone 远程仓库地址 三&#xff0c;创建shell脚本 touch shell.sh shell脚本 #!/bin/sh echo echo 自动…

健康手表数据洞察台

健康手表数据洞察台 1. 背景介绍2. 数据获取与处理3. Django平台搭建4. 数据可视化5. 整体数据分析6. 数据监控与紧急警报7. 用户界面优化8. 创新点结语 1. 背景介绍 在当今健康意识不断提升的社会&#xff0c;人们越来越关注身体健康。本文将介绍如何使用Pandas进行数据分析&…

NTC和温度的关系

一、NTC介绍 NTC&#xff08;nagative temperature coefficient&#xff09;负温度系数的热敏电阻。随着温度的升高&#xff0c;电阻越来越小 二、NTC和温度的关系 生产NTC的厂家会提供一个RT表格&#xff0c;里面记录了温度和电阻的关系&#xff0c;他们的关系是一一对应的…

C# 使用FluentHttpClient请求WebApi

写在前面 FluentHttpClient 是一个REST API 异步调用 HTTP 客户端&#xff0c;调用过程非常便捷&#xff0c;采用流式编程&#xff0c;可以将所有请求所需的参数一次性发送&#xff0c;并直接获取序列化后的结果。 老规矩从NuGet上安装该类库&#xff1a; 这边一定要认准是 P…

React系列:配置@别名路径并配置联想

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f492; 公众号&#xff1a;知识浅谈 &#x1f525;网站…

汽车火花塞行业分析:全球市场需求量约为26.3亿个

在汽车日常保养里,更换火花塞算是比较常见的一种,爱车懂车的车主们都非常清楚火花塞对于汽车的重要性,可以说火花塞直接影响到发动机的运作,决定了汽车能否顺利启程。 火花塞(sparkplug)&#xff0c;俗称火咀&#xff0c;它的作用是把高压导线(火嘴线)送来的脉冲高压电放电&…

zkSend — — 在Sui上发红包像发电子邮件一样简单

*12月14日&#xff0c;知名区块链媒体平台The Block发表了这篇关于对Mysten Labs联合创始人Adeniyi Abiodun的采访&#xff0c;文中“我们”指代该媒体&#xff0c;数据均为截止撰写文章时数据&#xff0c;以下是正文。 两年前&#xff0c;当五名前Facebook工程师创立Mysten L…

MySQL数据库 函数

目录 函数概述 字符串函数 数值函数 日期函数 流程函数 函数概述 函数是指一段可以直接被另一段程序调用的程序或代码。也就意味着&#xff0c;这一段程序或代码在MysQL中已经给我们提供了&#xff0c;我们要做的就是在合适的业务场景调用对应的函数完成对应的业务需求即…

如何提高股票交易速度?极速交易哪家好?

极速交易模式是一种交易方式&#xff0c;它以最短的时间进行快速交易。这种模式通常用于贵金属、外汇、原油、期权等金融产品的交易。 在极速交易模式中&#xff0c;交易者可以在最短时间内进行买卖操作&#xff0c;从而快速获取利润。这种交易方式通常需要高超的技术和经验&a…

【03】GeoScene创建海图或者电子航道图数据

1 配置Nautical属性 1.1 管理长名称 长名称&#xff08;LNAM&#xff09;是一个必要的对象标识符&#xff0c;是生产机构&#xff08;AGEN&#xff09;、要素识别号码&#xff08;FIDN&#xff09;和要素识别子项&#xff08;FIDS&#xff09;组件的串联。这三个子组件用于数…