【C++知识点总结全系列 (08)】:面向对象编程OOP

这里写目录标题

  • 1、OOP概述
    • (1)面向对象四大特征
      • A.抽象
      • B.封装
      • C.继承
      • D.多态
    • (2)构造函数
      • A.What(什么是构造函数)
      • B.Why(构造函数的作用)
      • C. Which(有哪些构造函数)
    • (3)析构函数
      • A.What(什么是析构函数)
      • B.Why(析构函数的作用)
    • (4) =default 和 =delete
      • A.Why
      • B.How
  • 2、继承
    • (1)What(什么是继承)
    • (2)Why(继承的作用)
    • (3)How(如何使用继承)
    • (4)虚函数
      • A.What
      • B.Why(虚函数的作用)
      • C.使用虚函数的注意事项
    • (5)虚析构函数
      • A.Why(虚析构函数的作用)
      • B.What(什么是虚析构函数)
    • (6)抽象基类
      • A.What(纯虚函数&抽象基类)
      • B.抽象基类的特点
    • (7)继承关系中的访问控制
      • A.类中成员的访问权限
      • B.类继承中的访问权限
      • C.派生类向基类转换的权限问题(向上转型)
      • D.友元在继承中的访问权限
    • (8)多重继承
      • A.横向多重继承:
      • B.纵向多重继承:
      • C.联合多重继承:
    • (9)虚继承
      • A.What(什么是虚继承、虚基类)
      • B.Why(虚继承的作用)
      • C.How
  • 3、多态(编译时多态)-重载
    • (1)输入输出运算符重载
    • (2)算术运算符:+、-、*、/
    • (3)关系运算符:>、>=、==、<=、!=
    • (4)赋值运算符
    • (5)下标运算符
    • (6)递增递减运算符
    • (7)解引用运算符和箭头运算符
    • (8)重载new和delete
      • A.Why(为什么要重载new和delete运算符)
      • B.How(如何重载)
    • (9)函数调用运算符
      • A.什么是函数对象
      • B.函数对象lamda

1、OOP概述

(1)面向对象四大特征

A.抽象

把一类东西的共同属性和方法提取到一个类中,而不关注具体如何实现

B.封装

对象属性对外接是隐藏的,只能通过对象的方法进行访问和修改

通过类实现对现实情况的抽象,使用private权限实现对类的封装

class Caculater{ 
private:int *Id; // 对数据进行封装,只有类能访问,外部智能通过提供的函数访问 
public:Caculater() { // 默认构造函数std::srand(std::time(nullptr)); int randomNumber = std::rand(); Id = new int;*Id = randomNumber; }Caculater(Caculater &caculater) { // 拷贝构造函数Id = caculater.getId();}~Caculater() { delete Id; } void showId(){if(Id) cout << "Id = " << *Id << endl; else cout << "nullptr" << endl;}template <class T, class U> auto add(const T &t, const U &u) const {return t + u; }int *getId() {return Id; }
};
template <typename T> 
void printf(const T &&t) { cout << t << endl; } 
int main(){// 隐式调用默认构造函数 Caculater caculater01; // 调用成员函数printf(caculater01.add(20, 10.1)); // 打印:30.1return 1;
}

C.继承

派生类可以继承基类的非私有属性和方法,而无需自己重新定义

D.多态

静态多态:编译时多态

函数重载或模板重载

动态多态:运行时多态

父类型可以指向其子类型的实例,使子类型对同一方法作出不同的回应,也就是所谓的动态绑定

动态绑定

通过基类指针或引用调用虚函数时,会根据实际对象的类型来确定要调用的函数版本 基类的引用或指针调用虚函数 virtual 时发生动态绑定

(2)构造函数

A.What(什么是构造函数)

一种特殊的成员函数:
一方面它没有返回值
另一方面它和类名相同

B.Why(构造函数的作用)

主要作用是创建初始化类对象:为对象的成员赋初始值、执行一些必要的初始化操作等

C. Which(有哪些构造函数)

无参构造函数

如果没有显式定义任何构造函数,编译器将自动生成一个默认构造函数(合成默认构 造函数)。它不带任何参数,并对类的成员进行默认初始化

带参构造函数

参数列表不为空的构造函数

Student(string strStuName, int iAge )
{	m_strStuName = strStuName;m_iAge = iAge;
}
Student(string strStuName, int iAge = 24)
{m_strStuName = strStuName;m_iAge = iAge;
}

拷贝构造函数

将参数中的对象深拷贝给当前对象,如果存在指针数据,一定要重新开辟空间,然后赋值

Student(const Student &stuObj)
{	this->strStuName = stuObj.getName();this->iAge = stuObj.getAge();this->ptrScore = new float(strObj.getScore());
}

移动构造函数

实现了数据的转移,相当于“鸠占鹊巢,还得把鹊赶尽杀绝”,移动赋值运算符同理

Student( Student &stuObj)
{this->strStuName = stuObj.getName();stuObj.setName("");this->iAge = stuObj.getAge();stuObj.setAge(0);this->ptrScore = new float(strObj.getScore());stuObj.score = nullptr;
}

转换构造函数

本质是带一个参数的构造函数,在需要时可以将其他类型的对象隐式转换为当前类的对象

(3)析构函数

A.What(什么是析构函数)

一个特殊的成员函数:
一方面,对象被销毁时自动调用,它不能是delete的
另一方面,和构造函数一样没有返回值

~Student(){delete this->ptrScore;ptrScore = nullptr;
}

B.Why(析构函数的作用)

  • 可用于释放动态分配的内存
  • 可用于关闭文件、数据库连接和网络连接资源
  • 解锁互斥量或释放其它同步资源

(4) =default 和 =delete

A.Why

更精确地控制类的成员函数的行为,提高代码的可读性和安全性

B.How

class MyClass { 
public:// 默认构造函数 MyClass() = default; // 默认析构函数~MyClass() = default; // 禁用拷贝构造函数MyClass(const MyClass&) = delete; // 禁用赋值运算符MyClass& operator=(const MyClass&) = delete; // 禁用移动构造函数MyClass(MyClass&&) = delete; // 使用默认移动赋值运算符MyClass& operator=(MyClass&&) = default;
};

2、继承

(1)What(什么是继承)

派生类从基类继承属性和方法

(2)Why(继承的作用)

重用性:派生类可以继承基类的属性和方法,减少重复代码的编写
扩展性:派生类可以在继承基类的基础上添加新的属性和方法,实现更强大的功能
多态性:实现对不同派生类的统一处理

说明:派生类的属性和基类重名时,会自动隐藏基类的成员

(3)How(如何使用继承)

class Derived: public Base{...}

(4)虚函数

A.What

一种特殊的成员函数,在基类中声明并用于被派生类重写的特殊成员函数

B.Why(虚函数的作用)

允许在运行时根据对象的实际类型来调用相应的函数实现,以实现多态性

C.使用虚函数的注意事项

  • override 关键字的使用:只有虚函数才能用 override 修饰(在派生类中使用该关键字)
  • 虚函数与默认实参:如果虚函数使用了默认实参, 则基类和派生类中定义的默认 实参应该一致,基类和派生类的虚函数必须接受相同的形参列表,否则无法实现动 态绑定
  • 回避虚函数机制:通常情况下,只有在成员函数(或友元)中使用作用域运算符来回避虚函数机制
    在这里插入图片描述

(5)虚析构函数

A.Why(虚析构函数的作用)

当我们使用基类指针或引用指向派生类对象,并且在基类指针或引用上删除该对象时, 如果基类的析构函数不是虚函数,则只会调用基类的析构函数,而不会调用派生类的 析构函数。这可能导致资源泄漏和未定义行为

B.What(什么是虚析构函数)

virtual ~Base();

在这里插入图片描述

注意:虚析构函数将阻止合成的移动构造函数和合成的移动赋值运算符,因为默认只 进行浅拷贝,而动态内存分配下的浅拷贝可能导致内存泄漏、悬挂指针等问题

(6)抽象基类

A.What(纯虚函数&抽象基类)

纯虚函数:
在这里插入图片描述
抽象基类:

含有纯虚函数的类叫做抽象基类

B.抽象基类的特点

  • 至少包含一个纯虚函数
  • 不能实例化对象,只能用作其他类的基类
  • 继承抽象基类的派生类必须实现纯虚函数,否则派生类也会称为抽象基类
  • 抽象基类可以包含非纯虚函数,提供默认或共享的功能

(7)继承关系中的访问控制

A.类中成员的访问权限

  • public:类的对象(外部)可以访问,派生类也可以访问
  • protected:类的对象(外部)不能访问,派生类可以访问
  • private:类的对象(外部)不能访问,派生类也不可以访问

B.类继承中的访问权限

  • public继承:public->public, protected->protected

    派生类可以继承基类中的公有成员和受保护成员,并将其作为自己的公有成员和受保护成员

  • protected继承:public&protected->protected

    将基类中的公有成员和受保护成员作为派生类的受保护成员

  • private继承:public&protected->private

    将基类中的公有成员和受保护成员作为派生类的私有成员,使得派生类无法直接访问这些成员

C.派生类向基类转换的权限问题(向上转型)

在这里插入图片描述
在这里插入图片描述
注意:派生类的成员函数和友元函数中,可以进行向上转型

D.友元在继承中的访问权限

  • 友元不能被继承:友元函数和友元类类似于基类的私有成员
  • 派生类的友元不可直接访问基类成员(包括公有成员)
    在这里插入图片描述在这里插入图片描述

(8)多重继承

A.横向多重继承:

在这里插入图片描述

B.纵向多重继承:

在这里插入图片描述

C.联合多重继承:

在这里插入图片描述

因为 single 和 waiter 都继承了一个 worker 组件,因此 SingingWaiter 将包含两个 worker 组件,那么将派生类对象的地址赋给基类指针将出现二义性

那么如何解决二义性问题呢?我们知道程序的执行一定是具有确定性的,在上述情况下,我们能想到的是进行强制转换,如下所示:
在这里插入图片描述
很显然,上述这种强制转换确实能够解决因联合继承带来的二义性问题,但是每次都进行这样的强制转换过于繁琐,那么有没有简单的办法解决二义性问题呢?答案就是:虚继承,所谓的虚继承,就是让共享一个祖父类

(9)虚继承

A.What(什么是虚继承、虚基类)

  • 虚继承:

class Derived: public virtual Base, 如下例所示,展示了虚继承的形式

在这里插入图片描述

  • 虚基类

被声明为虚继承的基类被称为虚基类

B.Why(虚继承的作用)

  • 解决二义性冲突:当基类的指针指向孙子类的指针或引用时,会出现二义性,因为 孙子类对象包含多个祖父类对象,而虚继承只保留一个共享的祖父类
  • 减少内存消耗:因为孙子类只包含一个祖父类对象
  • 减少代码冗余:虚基类的成员只需在最终的派生类中定义一次

C.How

在这里插入图片描述

3、多态(编译时多态)-重载

(1)输入输出运算符重载

以友元的形式进行重载:

在这里插入图片描述

(2)算术运算符:+、-、*、/

以友元的形式重载:

在这里插入图片描述

(3)关系运算符:>、>=、==、<=、!=

以友元的形式重载:

在这里插入图片描述

(4)赋值运算符

在这里插入图片描述

(5)下标运算符

在这里插入图片描述

(6)递增递减运算符

前置版本:
在这里插入图片描述
后缀版本:
在这里插入图片描述

注意:显式调用后置版本(默认调用前置版本)

在这里插入图片描述

(7)解引用运算符和箭头运算符

箭头运算符和解引用运算符必须是类的成员函数

在这里插入图片描述

(8)重载new和delete

A.Why(为什么要重载new和delete运算符)

重载 new 运算符和 delete 运算符是为了对内存分配和释放过程进行自定义操作,以 满足特定的需求。通过重载这些运算符,我们可以提供自定义的内存管理方法,例如 使用自定义的内存池,跟踪内存分配和释放情况,或进行性能优化

B.How(如何重载)

在这里插入图片描述
在这里插入图片描述

(9)函数调用运算符

函数调用运算符必须是成员函数

A.什么是函数对象

如果类定义了调用运算符,则该类的对象称为函数对象

在这里插入图片描述

B.函数对象lamda

在这里插入图片描述

lamda的引用捕获:

在这里插入图片描述

注意:使用[&]可以引用捕获作用域内所有变量

lambda的值捕获:

在这里插入图片描述

注意:使用[=]可以值捕获作用域内所有变量

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

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

相关文章

【YOLOv8系列】(一)YOLOv8介绍:实时目标检测的最新突破

目录 引言 背景与发展历程 YOLOv8架构设计 1. 改进的特征提取网络 2. 多尺度特征融合 3. 新的激活函数 4. Attention机制 模型训练与优化 性能评估 应用案例 目标检测 图像分割 图像分类 姿势估计 旋转框检测&#xff08;OBB&#xff09; 优势与挑战 优势&…

SAP PS学习笔记03 - 批量更改Project(CNMASS),批量创建Project(CNMASSCREATE)

上一章讲了网络&#xff08;Network&#xff09;&#xff0c;活动&#xff08;Activity&#xff09;&#xff0c;PS长文本&#xff0c; PS文书&#xff08;凭证&#xff09;&#xff0c;里程碑&#xff08;Milestone&#xff09;的创建等相关知识。 SAP PS学习笔记02 - 网络&a…

中西部公关新篇章:赛氪网赋能新质生产力赛事,引领行业潮流

2024年7月7日&#xff0c;武汉光谷盛况空前&#xff0c;中西部公共关系协会共同体多边合作平台&#xff08;以下简称“共同体”&#xff09;举办了2024年度中西部公关协会会长、秘书长专题交流会&#xff0c;本次会议主题为“加快新质生产力&#xff0c;推进公关行业新格局&…

思维+数学,CF 1138B - Circus

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1138B - Circus 二、解题报告 1、思路分析 设第一组会小丑和杂技的人数分别为x1, y1 第二组会小丑和杂技的人数分别为x2, y2 显然根据要求有&#xff1a; x1 y2 > x1 x2 x2 y2 上式说明第二组每…

213.贪心算法:跳跃游戏||(力扣)

class Solution { public:int jump(vector<int>& nums) {if (nums.size() 1) return 0; // 如果数组长度为1&#xff0c;已经在终点&#xff0c;不需要跳跃int cur 0; // 当前跳跃能到达的最远位置int flag 0; // 记录跳跃次数int next 0; // 下一次跳跃能到…

0302GPIO外设输入功能

GPIO外设输入功能 输入部分硬件电路按键简介传感器模块简介按键和传感器模块的硬件电路 C语言的学习C语言数据类型宏定义typedef结构体枚举C语言知识总结 按键控制LED灯&光敏传感器蜂鸣器GPIO总结GPIO使用方法总结模块化编程的方法&#xff1a; 两个程序&#xff1a;按键控…

PostgreSQL 里怎样解决多租户数据隔离的性能问题?

文章目录 一、多租户数据隔离的性能问题分析&#xff08;一&#xff09;大规模数据存储和查询&#xff08;二&#xff09;并发访问和锁争用&#xff08;三&#xff09;索引维护成本高&#xff08;四&#xff09;资源分配不均 二、解决方案&#xff08;一&#xff09;数据分区&a…

计算理论复习

1.Turing Machine 确定性图灵机 图灵机有很多不同的定义&#xff0c;这里选取其中一种&#xff0c;其它定义下的图灵机往往与下面这种定义的图灵机计算能力等价。 图灵机是一个在一条可双向无限延伸且被划分为若干格子的纸带上进行操作的机器&#xff0c;其有内部状态&#…

Springboot项目实训--day2

今天学习的是idea和MySQL的连接&#xff0c;以及一些基本的增删改查的功能实现。 一、软件下载 昨天下载了idea&#xff0c;今天要是西安它们的连接&#xff0c;就需要再下载MySQL&#xff0c;我的MySQL是前面几个学期别人帮忙下载的&#xff0c;所以具体的操作步骤我也不清楚…

基于Java+SpringMvc+Vue技术的智慧校园系统设计与实现

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…

3-6 构建线性模型解决温度计示数转换问题

3-6 构建线性模型解决温度计示数转换问题 直接上源码 %matplotlib inline import numpy as np import torch torch.set_printoptions(edgeitems2, linewidth75)导入必要的库并设置 PyTorch 的打印选项&#xff0c;确保在打印张量时显示边缘项和行宽。 #%% t_c [0.5, 14.0,…

window.matchMedia

matchMedia() 返回一个新的 MediaQueryList 对象&#xff0c;表示指定的媒体查询字符串解析后的结果。 const width ref(); const myFunction (x) > {if (x.matches) {// 媒体查询document.body.style.backgroundColor "yellow";width.value "yellow&quo…

alibabacloud学习笔记11

讲解什么是配置中心及使用前后的好处 讲解Nacos作为配置中心面板介绍 官方文档 Nacos config alibaba/spring-cloud-alibaba Wiki GitHub 加入依赖&#xff1a; 订单服务和视频服务也加上这个依赖。 讲解Nacos作为配置中心实战 订单服务添加配置。 我们注释掉之前的配置。 …

乐鑫ESP-NOW与Wi-Fi SoC方案家居设备无缝连接,启明云端乐鑫代理商

随着科技的不断进步&#xff0c;智能家居逐渐成为现代生活的一部分。ESP-NOW技术以其独特的无线通信能力&#xff0c;为智能家居领域带来了一场革命。 ESP-NOW是一种由乐鑫定义的无线通信协议&#xff0c;它能够在无需路由器的情况下&#xff0c;实现设备间的直接、快速、低功…

事务性数据系统中复制与 S3 Express One Zone 的成本分析

原文链接&#xff1a;https://jack-vanlightly.com/blog/2024/6/10/a-cost-analysis-of-replication-vs-s3-express-one-zone-in-transactional-data-systems作者&#xff5c;Jack Vanlightly AutoMQ 导读 随着 S3 在构建现代化数据基础设施的流行&#xff0c;广大 data in…

【免费的车间数据监控大屏】车间管理的新利器,让生产效率一目了然

面对生产车间里各种繁杂的数据&#xff0c;你不会还在用Excel敲击一个个无聊的数据吧&#xff1f;怎么不试试生动形象的车间数据看板呢&#xff1f; 在繁忙的车间里&#xff0c;每一寸空间都跳动着生产的脉搏&#xff0c;而车间数据监控看板&#xff0c;就像是这个舞台上的“智…

注解复习(java)

文章目录 注解内置注解**Deprecated**OverrideSuppressWarnings【不建议使用】Funcationallnterface 自定义注解元注解RetentionTargetDocumentedInherited 和 Repeatable 反射注解 前言&#xff1a;笔记基于动力节点 注解 注解可以标注在 类上&#xff0c;属性上&#xff0c…

opencv颜色识别,hsv采用滑块调节

识别效果如图所示&#xff0c;尽量排除了蓝色背景的干扰&#xff0c;hsv可用滑块进行调节&#xff0c;更加方便 import cv2 import numpy as np# 创建一个命名窗口&#xff0c;用于显示滑块 cv2.namedWindow("TrackBar")def nothing(x):pass# 创建滑块控件 cv2.cre…

Python深度学习

原文链接&#xff1a;Python深度学习https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247608512&idx1&sn16e2a0bb6b0a1f6b513be173730090c0&chksmfa826927cdf5e031b702deb04eef5cb0055f65b0d6e4c33588949ee81c7380ee044caeafd8c7&token2068755524&am…

arp缓存中毒实验

文章目录 一、相关知识1.什么是arp&#xff08;地址解析协议&#xff09;2.什么是免费arp&#xff08;1&#xff09;简介&#xff08;2&#xff09;主要应用&#xff08;3&#xff09;代码 3.什么是arp缓存中毒&#xff08;1&#xff09;简介&#xff08;2&#xff09;过程&…