C++(面向对象之继承、多态)

一、继承

前言

在c++里面,继承是指2个类之间的关系

例如:有一个org类,功能很完善,体量很大,突然有一天,需求发生改变,org类不能满足新的需求,我们的第一想法是,复制 org 类代码,粘贴成 new 代码,然后在new代码里面写新的函数,以满足新需求,但是我们有时无法复制粘贴,有可能体量太大,复制不方便。有可能该类我们没有源代码,没有办法去复制,所以我们应该使用继承,让new类继承自 org类,一旦继承过后,new类即使什么都不写,就会天然的拥有org类里面所有的数据和函数

在继承里面:
org类:  我们称为父类 或者 基类
new类:我们称为子类 或者 派生类

1、继承的语法格式

class org{    
}
class new:public/protected/private org{
}

2、三种继承方式

        继承类时有 public / protected / private 三种继承方式

1)不同继承方式下基类的访问权限

原有权限  \  继承方式publicprotectedprivate
publicpublicprotectedprivate
protectedprotectedprotectedprivate
privateprivate(被隐藏)private(被隐藏)private(被隐藏)

在继承中 protected 和 private 的区别

在继承过后,派生类无法内部访问基类的私有成员,但是派生类可以内部访问基类的受保护成员

 2)继承的本质

其实继承就相当于复制粘贴,只是复制粘贴这一步是由编译器在编译那一步完成的

3、继承到底继承哪些内容

1)可以继承的内容

运算符重载函数、静态成员属性、静态成员方法、构造函数和析构函数

        构造函数和析构函数要特别注意,虽然派生类继承了基类的构造函数和析构函数,但是并不是说将基类的构造函数和析构函数继承给派生类作为构造函数和析构函数,只是继承在派生类中,在构造和析构基类的对象时可以调用。 

2)不能继承的内容

友元函数:是关于类的一种关系,并不是类的成员,自然不能继承

4、初始化及访问基类私有成员

1)初始化基类的私有成员

私有成员不论是派生类还是基类,都只能类中访问,构造类中的成员也只能由自己的构造函数完成
因此可以在派生类的初始化列表中调用基类的构造函数来初始化。

注意:派生类只能调用直接基类的构造函数,不能夸辈调用构造函数。
例如:A继承B,B继承C,A可以调用B的构造函数,但是不能调用C的构造函数

2)访问基类私有成员 

外部访问类的私有成员需要类中设有公开接口才能访问,派生类访问基类的私有成员也是一样的

5、基类、派生类、派生类中的对象的构造顺序

在构建派生类对象时,按照执行顺序,会先构造基类,再构建派生类中的对象,最后是派生类自己

构造的顺序是:
基类 -> 派生类中的对象 -> 派生类本身

析构的顺序是:(遵循先进后出原则,先构建的后析构)
派生类本身 -> 派生类中的对象 -> 基类

6、基类、派生类中的重名函数或变量

7、继承关系

1)多级继承

2)继承组

3)多重继承

4)菱形继承

8、多重继承

9、菱形继承

1)菱形继承存在的问题

2)virtusl(虚继承)

二、多态

前言

多态是指,基类可以调用多个不同派生类对象的成员方法的能力

1、多态的实现

1)多态是通过virtual (虚函数) 来实现的(步骤)

  1. 声明虚函数:在基类中用关键字virtual 声明虚函数
  2. 重写虚函数:将派生类中要调用的函数名重写,与虚函数名同名同参
  3. 通过引用/指针调用:使用基类类型的指针或引用指向派生类的对象,并调用基类的虚函数

2)示例

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <vector>
#include <memory>
#include <unistd.h>using namespace std;class Core{private:public:virtual void func()//声明虚函数{cout << "基类函数" << endl;}
};class Core_pro:public Core{private:public:void func()//将想要调用的函数写为和虚函数同名同参的函数{cout << "派生类函数1" << endl;}
};class Core_pro_max:public Core{private:public:void func()//将想要调用的函数写为和虚函数同名同参的函数{cout << "派生类函数2" << endl;}
};class Person{private:public://以引用类型接收变量,调用不同派生类的成员方法void work1(Core& c){c.func();}//以指针类型接收变量,调用不同派生类的成员方法void work2(Core* c){c->func();}
};      int main(int argc,const char** argv)
{Core c;Core_pro cp;Core_pro_max cpm;Person zs;//传入变量zs.work1(c);zs.work1(cp);zs.work1(cpm);//传入地址zs.work2(&c);zs.work2(&cp);zs.work2(&cpm);return 0;                        
}

3)多态作业练习:

1:写一个Msg消息队列类,要求有以下功能Msg m() 构造函数,创建消息队列m[1] << "hello" 向消息队列的1频道写入数据"hello",当然可以是其他的字符串数据m[2] >> str :从2频道读取消息,并且将读到的消息存入str中析构函数:删除消息队列

2:写一个员工类 Employee,有一个多态函数叫做 getSalary有一个 Cleanner 保洁类,继承自员工类:每个月获得 5000 工资有一个 Coder 程序员类,继承自员工类,每个月获得 10000工资有一个 Manger 经理类,继承自员工类,每个月获得 15000工资写一个发工资的函数,要求,能够为所有员工发放工资,即使追加新的岗位,也不会改变这个函数的逻辑

3:写一个基类叫做颜色写3个派生类,红绿蓝以及需要存在的其他颜色,继承自颜色类要求实现以下功能:Red rGreen g;Color new_color = r + gnew_color.show() ;// 终端输出 "黄色"


2、多态的原理

1)解析

  1. 多态的过程,其实是在基类的作用域中找到派生类的成员方法的过程
  2. 在基类中写入虚函数后,基类会含有一个指针,就是虚函数指针,该指针指向虚函数列表
  3. 继承,过程中,编译器会将基类深拷贝到派生类中,自然也会拷贝虚函数列表;
  4. 重写虚函数(覆盖),编译器会将派生类的虚函数,覆盖到基类的虚函数列表中;
  5. 查找成员方法时,由于派生类的虚函数被重写到基类中,自然就只能查找到基类中的虚函数

2)多态的总结

  1. 基类有虚函数,就会有虚函数列表,所有虚函数都存放在虚函数列表里面
  2. 派生类继承自基类的时候,同时继承了虚函数列表
  3. 派生类重写基类虚函数的时候,就会将虚函数列表中的基类的虚函数给覆盖

为什么会覆盖:因为同名同参,又在同一作用域中,不覆盖会出现问题,也因此派生类重写基类虚函数的行为,也叫覆盖(2个名字,可以叫重写,可以叫覆盖)

3)函数重载和函数重写的区别

  1. 函数重载:要求写在同一个作用域中,函数重写:要求在不同作用域中
  2. 函数重载:要求同名不同参,函数重写:要求同名同参
  3. 函数重载:是静态多态,又被称作编译期多态
    函数重写:是动态多态,又被称作运行期多态

3、多态的继承方式

多态的继承方式:公开继承(public)(想要多态,就必须使用公开继承)

多态访问派生类函数:
实际上是通过派生类中,指向基类内部虚函数列表的指针,去访问的;
并且虚函数列表的访问权限也是收到继承权限的限制的;
因此,虚函数列表,必须是公开继承,才能实现多态

4、多态中的析构函数

5、纯虚类

1)纯虚类的特点

2)纯虚类的创建

创建纯虚类只需要保证类中,至少拥有一个纯虚函数

(1)什么是纯虚函数

纯虚函数是没有定义的,不能被调用的

(2)怎么设置纯虚函数
  • 将函数设置为虚函数
  • 直接将 "声明部分" =0 即可

3)纯虚类的作用

6、设计模式

设计模式:其实就是针对多态,各种方式的公式化运用

1)设计模式的五大原则

(1)接口隔离(独立)原则
(2)开闭原则
(3)单一原则
(4)依赖倒置原则
(5)里氏替换原则

2)策略模式


3)代理模式


4)观察者模式


5)简单工厂模式



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

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

相关文章

【数据可视化-75】北京密云区2025年7月暴雨深度分析:Python + Pyecharts 炫酷大屏可视化(含完整数据、代码)

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

Voxtral Mini:语音转文本工具,支持超长音频,多国语音

Voxtral是什么 Mistral AI 推出的 Voxtral 是一款强大的音频模型&#xff0c;专为语音交互打造&#xff0c;具备卓越的语音转写和语义理解能力。它提供 24B 和 3B 两种版本&#xff0c;分别适用于大规模生产和本地部署。Voxtral 支持多语言、长文本上下文、问答与总结&#xf…

React Native环境配置完整版(超详细)

目录 第一步&#xff1a;打开React Native官方网站 第二步&#xff1a;安装NVM与Node.js 一、安装NVM 二、使用NVM安装Node.js 三、NVM使用说明 四、环境变量配置 第三步&#xff1a;安装JDK 一、JDK介绍 二、下载与安装JDK 三、环境配置 四、验证是否配置成功 第四…

Rust 最短路径、Tide、Partial、Yew、Leptos、数独实践案例

基于Rust的Meta和pyrefly相关实例 以下是一些基于Rust的Meta和pyrefly相关实例的示例代码和用法。这些示例涵盖了常见的使用场景,包括元编程、代码生成、Python交互等。 基本元编程示例 使用Rust的宏和元编程功能生成代码。 macro_rules! greet {($name:expr) => {prin…

Microsoft-DNN NTLM暴露漏洞复现(CVE-2025-52488)

免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 前…

Windows上WSL2实例与宿主机桥接网络实现局域网互通

在 WSL 2 中&#xff0c;默认使用 NAT 网络模式&#xff0c;这会导致 WSL 实例和宿主机所在的局域网无法直接互通。要让 WSL 2 和宿主机所在的局域网互通&#xff0c;可以通过以下步骤配置 wsl.conf 并结合宿主机网络设置&#xff0c;启用 WSL 2 的桥接模式&#xff1a;修改 ws…

程序代码篇---数据包解析

数据包解析是不同设备&#xff08;如电脑、ESP32 等嵌入式设备&#xff09;之间通信的核心环节。简单说&#xff0c;就是把收到的 "一串数据" 翻译成双方都能理解的 "具体信息"&#xff08;比如温度、湿度、命令等&#xff09;。下面介绍几种常见的数据包格…

【开发杂谈】用AI玩AI聊天游戏:使用 Electron 和 Python 开发大模型语音聊天软件

项目地址&#xff1a; GitHub | wfts-ai-chathttps://github.com/HiMeditator/wfts-ai-chat 前言 最近一个基于 AI 的聊天游戏 Whispers from the Stars&#xff08;群星低语&#xff09;的 Demo 版本发布了。《Whispers from the Star》是一款科幻主题互动游戏。背景设定在…

SQL优化系统解析

MySQL的安装就不讲述了, 本篇文章着重讲解sql优化 本篇是对B站颜群老师视频讲解的笔记梳理, 感兴趣的可以去看下老师的原视频: SQL优化 MySQL原理 1. MySQL逻辑分层: 连接层->服务层->引擎层->存储层(如图) 连接层&#xff1a;提供与客户端连接的服务服务层&#…

【机器学习案列-25】电信用户流失预测:从数据处理到模型评估

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

【MATLAB代码】灰色预测与多项式预测、指数平滑预测的对比,包含预处理、模型构建和和可视化输出。模拟预测若干年的GDP,订阅后可查看完整代码,有中文注释

代码实现了灰色预测模型GM(1,1)在GDP预测中的应用,并结合线性回归、二次多项式回归和指数平滑模型进行对比分析。代码包含数据预处理、模型构建、可视化输出和误差验证四个核心模块,实现了从数据输入到预测结果展示的全流程。 文章目录 运行结果 MATLAB源代码 GM(1,1)模型数学…

搜索二维矩阵Ⅱ C++

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {i…

如何在 Apache Ignite 中创建和使用自定义 SQL 函数(Custom SQL Functions)

这段内容讲的是 如何在 Apache Ignite 中创建和使用自定义 SQL 函数&#xff08;Custom SQL Functions&#xff09;。我们可以分步骤来理解它的含义和用法。&#x1f4da; 一、什么是 Custom SQL Function&#xff1f; Apache Ignite 的 SQL 引擎支持 标准 SQL 函数&#xff08…

Oracle 11g RAC数据库实例重启的两种方式

Oracle 11g RAC数据库实例重启的两种方式 使用SQLPlus重启数据库实例 使用SRVCTL重启数据库实例 Administrator-Managed还是Policy-Managed 📖 关于关闭RAC的数据库实例: 在Oracle RAC中,单独关闭一个实例不会影响到其他正在运行的实例。 要完全关闭Oracle RAC数据库,需要…

分别使用 Java 8 和 Python 调用 Elasticsearch 接口简单获取数据

使用 Java 8 首先,确保在您的 pom.xml 文件中添加了正确的 Maven 依赖: <dependency><groupId>co.elastic.clients</groupId><artifactId>elastic

【通识】数据结构

数据结构逻辑结构物理结构&#xff08;存储结构&#xff09;&#xff0c;数据结构是计算机中存储、组织数据的方式。 其中物理结构是数据的逻辑结构在计算机中的存储形式。而存储器针对内存而言&#xff0c;像硬盘、软盘、光盘等外部存储器的数据组织常用文件结构描述。1. 基础…

Ubuntu22.04提示找不到python命令的解决方案

Ubuntu22.04提示找不到python命令的解决方案 问题背景 在Ubuntu22.04中按照获取Openharmony源码中的如下命令&#xff1a; // 方式一&#xff08;推荐&#xff09;&#xff1a;通过repo ssh下载&#xff08;需注册公钥&#xff0c;请参考码云帮助中心&#xff09;。repo in…

RabbitMQ面试精讲 Day 6:消息确认与事务机制

【RabbitMQ面试精讲 Day 6】消息确认与事务机制 开篇 欢迎来到"RabbitMQ面试精讲"系列的第6天&#xff01;今天我们将深入探讨RabbitMQ中确保消息可靠性的两大核心机制&#xff1a;消息确认与事务机制。这两个特性是面试中高频出现的热点问题&#xff0c;也是生产环…

被困扰的elementplus样式修改问题:select选择器修改和el-input修改

一、Select选择器的原生样式的本来面貌这是原生的没有经过任何加工的面貌&#xff1a;这是没有经过任何加工的选中时出现下拉框的面貌&#xff1a;这是没有经过加工的悬浮下拉菜单的面貌&#xff1a;这是没有经过加工的选中时的面貌&#xff1a;二、如何修改Select选择器&#…

GO 从入门到精通2

Go语言的反射&#xff08;Reflection&#xff09;机制通过 reflect 包实现&#xff0c;允许程序在运行时动态检查、修改和操作变量的类型信息和值。以下是反射的核心概念、用法及注意事项的详细解析&#xff1a;一、反射的基本概念reflect.Type 表示变量的类型信息&#xff0c;…