C++学习笔记----9、发现继承的技巧(一)---- 使用继承构建类(1)

news2024/11/26 13:43:55

        在前面的章节中,你学到了继承关系是一种真实世界对象以层次存在的模式。在编程世界中,当需要写一个类基于其构建,或进行细微的修改的另一个类时,那种模式就有了关系。完成这个目标的一个方式是拷贝一个类的代码粘贴到另一个类中。修改相关部分或者改变代码,就能达到生成一个新类,与原来的类有一点不同的目标。这个方法,真的不怎么样,让面向对象编程的程序员感到憋屈与冒犯,有以下的原因:

  • 对原有类的问题修复不会反映在新的类中,因为这两个类包含完全独立的代码。
  • 编译器不知道这两个类之间的关系,所以它们不是多态--它们也不是同一件事的不同的变形。
  • 这个方法并没有建立一个真正的继承关系。新类与原来的类相似只是因为有相似的代码,而不是因为是同类型的对象。
  • 原来的代码有可能获取不到。它可能会只存在于预编译的二进制格式,所以拷贝粘贴代码可能变得不可行。

        一点儿也不奇怪,c++提供内置的对于真正的继承关系定义的支持。c++继承关系的特点会成为我们接下来讨论的内容。

1、扩展类

        当你写一个在c++中定义的类时,可以告诉编译器你的类是继承自,源于,或扩展自一个既有类。这样做的话,你的类就会自动包含原有类的数据成员与成员函数,原有类叫父类,基类,或超类。扩展一个既有类给你的类(它现在叫做子类,派生类,扩展类)唯一的描述它与父类不同的能力。

        在c++中扩展一个类,在写类定义时指定要扩展的类。要展示继承的语法,会用到两个类,基类与派生类。别担心--更有趣的例子后面马上来。一开始,先考虑下面Base类的定义:

class Base
{
public:
	void someFunction() {}

protected:
	int m_protectedInt{ 0 };

private:
	int m_privateInt{ 0 };
};

        如果你想要构建一个叫做Derived的新类,它继承自Base,使用下面的语法:

class Derived : public Base
{
public:
	void someOtherFunction()
	{
		println("I can access base class data member m_protectedInt.");
		println("Its value is {}", m_protectedInt);
		//println("The value of m_privateInt is {}", m_privateInt); // Error!
	}
};

        Derived是一个成熟的类,只是碰巧共享了Base类的属性。现在不要担心public关键字--我们后面会解释。下图展示了Derived与Base之间的简单关系。

        可以像其它对象一样声明Derived类型的对象。甚至可以定义第三个类继承自Derived,弄成类的链条,如下图所示:

        Derived不必是Base的唯一的继承类。另外的类也可以继承自Base,可以高效地变成Derived的兄弟姐妹,如下图所示:

        在系统内部,继承类包含了基类的实例,叫做子对象。可以图示如下:

1.1、继承的客户视角

        对于客户来说,或者代码的另外部分来说,Derived类型的对象也是一个Base类型的对象,因为Devived继承自Base。这意味着Base的所有的公共的成员函数与数据成员以及Derived的所有公共成员函数与数据成员都是可用的。

        为了调用它,使用继承类的代码不需要知道在继承链条中哪个类定义了一个成员函数。例如,下面的代码调用了Derived对象的两个成员函数,即使其中一个成员函数定义在Base类中:

	Derived myDerived;
	myDerived.someFunction();
	myDerived.someOtherFunction();

        理解继承类是沿着一个方向工作的是很重要的。Derived类对Based类有一个清晰定义的关系,但是Base类,如字面意思,不会知道Derived类的任何信息。这意味着Base类型的对象无法访问Derived的成员函数与数据成员,因为Base不是Derived。

        下面的代码编译不会成功,因为Base类不包含一个公共的叫做someOtherFunction()的成员函数:

	Base myBase;
	myBase.someOtherFunction();  // Error! Base doesn't have a someOtherFunction().

        注意:从使用对象的代码的角度,对象属于它定义的类,也属于任何基类。

        对类类型的指针或引用可以指向声明的类类型或它的任何继承类。我们后面专门讨论这个令人迷惑的话题。现在要理解的概念是指向Base的指针实际上也可以指向一个Derived对象。对于引用也一样。客户仍然可以访问存在于Base中的成员函数与数据成员,但是通过这种技术,在Base上可以操作的代码也可以在Derived上操作。

        例如,下面的代码编译与运行都没有问题,即使一开始会出现一个类型不匹配:

Base* base{ new Derived{} }; // Create Derived, store in Base pointer.

        然而,不能通过Base指针调用Derived类的成员函数。下面的代码是不灵的:

base-­>someOtherFunction();

        这会被编译器标记为错误,因为虽然对象是Derived类型,也确实定义了someOtherFunction(),但是编译器只会认为它的类型是Base,而Base是没有定义someOtherFunction()的。

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

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

相关文章

一个月学会Java 第14天 内部类

Day14 内部类 类有外边的public class,然后还有一个文件多个的class,但是有没有想过,class可以作为成员也就是类内部的类,甚至作为方法内部的属性也就是类内部的方法的内部出现。除了这两个, 还有直接对着上节课讲的抽…

GeoScene Pro教程(008):GeoScenePro数据查询和检索

文章目录 1、工具分类2、数据常用工具2.1 加载数据2.2 查询需求2.2.1 按照属性查询查询1:人口大于300万的城市有哪些查询2:自治州有哪些查询3:城市名字中带有“荆”的有哪些补充2.2.2 按照位置查询需求2:导出湖北省境内的铁路数据需求3:武汉市共有多少条铁路2.2.3 空间连接…

48 Redis

48 Redis 前言 Redis(Remote Dictionary Server ),即远程字典服务。是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 redis会周期性的把更新的数据写入磁盘或者把修改操…

RTSP与ONVIF协议的区别及其在EasyCVR视频汇聚平台中的应用

在视频监控和物联网设备领域,RTSP(Real Time Streaming Protocol)和ONVIF(Open Network Video Interface Forum)是两个重要的协议,它们各自在视频流的传输和控制上发挥着不同的作用,并在实际应用…

网络安全之XXE攻击

0x01 什么是 XXE 个人认为,XXE 可以归结为一句话:构造恶意 DTD 介绍 XXE 之前,我先来说一下普通的 XML 注入,这个的利用面比较狭窄,如果有的话应该也是逻辑漏洞。 既然能插入 XML 代码,那我们肯定不能善罢…

基于Nodemcu的手机控制小车

基于Nodemcu的手机控制小车 一、项目说明二、项目材料三、代码与电路设计四、轮子和车体五、电路连接六、使用方法 一、项目说明 嗨,机器人项目制造者们!在这个项目中,我制作了这辆简单但快速的遥控车,它可以通过智能手机控制&am…

gaussdb 主备版本8 SQL参考 学习

SQL参考 1 数据类型 1.1 货币类型 1.1.1 货币类型存储带有固定小数精度的货币金额。 1.2 布尔类型 1.2.1 true:真 1.2.2 false:假 1.2.3 null:未知(unknown) 1.3 日期/时间类型 1.3.1 DATE 输出格式:仅支…

MySQL-06.DDL-表结构操作-创建

一.DDL(表操作) create database db01;use db01;create table tb_user(id int comment ID,唯一标识,username varchar(20) comment 用户名,name varchar(10) comment 姓名,age int comment 年龄,gender char(1) comment 性别 ) comment 用户表; 此时并没有限制ID为…

圈子系统APP小程序H5该如何设置IM?

搭建圈子系统的常见问题,以及圈子论坛系统的功能特点 社交圈子论坛系统的概念 圈子小程序源码 多客圈子系统 圈子是什么软件 跟进圈一个系统的软件 为圈子系统APP小程序H5设置IM(即时通讯),需要遵循一系列步骤来确保通讯功能的稳定、安全和高…

企业架构之从理论指南到实践指导企业数字化转型

理论与实践结合的数字化转型之道 在当今的全球化经济中,企业面临着前所未有的数字化转型压力。数字化转型不仅是技术的更新换代,更是业务、组织、文化和战略的系统性重塑。对于企业来说,如何将理论转换为有效的实践路径,是推动数…

STM32 通用同步/异步收发器

目录 串行通信基础 串行异步通信数据格式 USART介绍 USART的主要特性 USART的功能 USART的通信时序 USART的中断 串行通信基础 在串行通信中,参与通信的两台或多台设备通常共享一条物理通路。发送者依次逐位发送一串数据信号,按一定的约定规则被接…

乐鑫ESP32-S3无线方案,AI大模型中控屏智能升级,提升智能家居用户体验

在这个由数据驱动的时代,人工智能正以其前所未有的速度和规模改变着我们的世界。随着技术的不断进步,AI已经从科幻小说中的概念,转变为我们日常生活中不可或缺的一部分。 特别是在智能家居领域,AI的应用已成为提升生活质量、增强…

linux下编译鸿蒙版curl、openssl

一.环境准备 1.参考说明 NDK开发介绍:https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/napi/ndk-development-overview.md 2.NDK下载 点击介绍页面中的链接可以跳转到相应下载页面: 下载相应版本: 下载完毕后解压到指定目…

Matlab详细学习教程 MATLAB使用教程与知识点总结

Matlab语言教程 章节目录 一、Matlab简介与基础操作 二、变量与数据类型 三、矩阵与数组操作 四、基本数学运算与函数 五、图形绘制与数据可视化 六、控制流与逻辑运算 七、脚本与函数编写 八、数据导入与导出 九、Matlab应用实例分析 一、Matlab简介与基础操作 重点内容知识…

第2章 STM32最小系统介绍

第2章 STM32最小系统介绍 1. STM32最小系统组成 2. STM32启动模式 1.STM32最小系统组成 (1)电源电路 (2)复位电路 (3) 晶振电路 (4)下载电路 可打开开发板原理图查看 2.STM32启动模式 在STM…

Postman最新V11版本关键更新一览

Postman作为接口测试中,被广泛应用的一款主流工具,以其丰富的功能,灵活方便的使用方式,广受欢迎。最新发布的V11版本则在向协作平台转型的过程中一路狂奔,增加大量全新的协作支持。下面我们就一起来看看都有哪些变化吧…

基于Arduino的泡茶机器人

打造你的完美泡茶助手 引言 你是否曾遇到过泡出的茶太淡或太苦?通过这个项目,你可以创建一个设备,为你的茶包提供完美的浸泡时间。只需附上一个茶包并放置你的杯子,设备就会开始工作!它将完美地按照你的喜好浸泡你的…

数通--3

一、动态路由 内部 路由器之间要互联互通,必须遵循相同的协议 企业内部用 IGP,企业之间用BGP RIP(已淘汰,不考) 距离就是长短,矢量就是方向,即路由的出接口 一台路由器 A 配好RIP,…

【Fargo】5:根据网络带宽动态调整发送速率

根据网络带宽动态调整发送速率 原理:这个简单实现的原理是 改变包的发送速率就可以改变发送码率了。例如1秒发1000个1KB 的包,带宽8Mbps,如果带宽是4Mbps,那么1秒发500个就够了。D:\XTRANS\thunderbolt\ayame\zhb-bifrost\player-only\worker\src\fargo\zhb_uv_udp_sender.…

好书分享《大模型应用开发极简入门》

本书为大模型应用开发极简入门手册,为初学者提供了一份清晰、全面的“可用知识”,带领大家快速了解GPT-4和ChatGPT的工作原理及优势,并在此基础上使用流行的Python编程语言构建大模型应用。 通过本书,你不仅可以学会如何构建文本生…