【PL理论】(29) OOP:面向对象编程 | 案例研究:C++ 中的类 | 继承 | 继承和指针 | Object-oriented Programming

  • 💭 写在前面:本章我们将进入 Object-oriented Programming,面向对象编程的讲解,探讨 C++ 中的类,继承等。

目录

0x00 面向对象编程

0x01 C语言中的结构体

0x02 案例研究:C++ 中的类

0x03 术语

0x04 继承:动机

0x05 继承和指针


0x00 面向对象编程

另一种重要的编程语言范式,编程是对象的创建和交互。

对象是相关数据和代码的集合,数据 = 属性 (字段) ,代码 = 方法 (函数)。

通常,对象对应于现实世界中的某物。

例如网站系统中的学生对象,网页浏览器引擎中的 HTML 元素对象。

许多现代编程语言在某种程度上支持面向对象编程的概念,例如:C++,Java,Python...

0x01 C语言中的结构体

让我们回顾一下C语言 (它不被认为采用面向对象编程)

struct 用于将一组数据定义为一种新类型,处理这种结构体的函数是单独定义的。

struct Student {int id;char name[32];...
};void printStudent(struct Student *x) {printf("ID: %d\n", x->id);...
}

0x02 案例研究:C++ 中的类

在 C++ 中,我们定义和使用类,将相关数据 (属性) 和代码 (方法) 绑定在一起。

这种类后来被用来创建对象 (实例),我们还使用访问修饰符 (public 和 private) 来隐藏内部细节,使其不被外部访问。

class Student {private:int id;string name;public:void Print() {cout << "ID: " << id << endl;cout << "Name: " << name << endl;}...
};

0x03 术语

封装 (Encapsulation) :将相关数据和代码绑定在一起

抽象 (Abstraction) / 信息隐藏 (info hiding):仅暴露必要信息,省略实现细节

我们将学生定义为支持 Print() 等功能的对象,我们使内部细节无法从外部访问。

class Student {private:int id;string name;public:void Print() {cout << "ID: " << id << endl;cout << "Name: " << name << endl;}...
};

0x04 继承:动机

假设我们要开发学生管理系统,让我们定义 Student 和 Professor 类如下 (注意这次我们为学生添加了 GPA 属性),这两个类共享一些属性和方法。

class Student {
private:int id;string name;double GPA; // Grade Point
public:int GetID() { return id; }string GetName() { return name; }double GetGPA() { return GPA; }void Print() { ... }
};class Professor {
private:int id;string name;string office; // Office room No.
public:int GetID() { return id; }string GetName() { return name; }string GetOffice() { return office; }void Print() { ... }
};

然后,这两个类的对象必须分别存储和处理,在下面的示例中,我们必须有单独的数组 (students 和 profs) 和函数 (printStudents 和 printProfs) 。

void printStudents(Student* students[]) { ... }
void printProfs(Professor* profs[]) { ... }
int main() {Student* students[MAX_N] = { NULL };Professor* profs[MAX_N] = { NULL };students[0] = new Student(...);profs[0] = new Professor(...);...printStudents(students);printProfs(profs);return 0;
}

相反,我们可以从这两个类中提取共同特征,并将其定义为 UnivMem 类,然后,Student 和Professor 类将继承这个类。目前,假设只有UnivMem类具有 Print() 方法。

class UnivMem {
private:int id;string name;
public:int GetID() { return id; }string GetName() { return name; }void Print() { ... }
};class Student : public UnivMem {
private:double GPA;
public:double GetGPA() { return GPA; }
};class Professor : public UnivMem {
private:string office;
public:string GetOffice() { return office; }
};

现在,UnivMem 指针可以指向 Student 或 Professor 对象,隐式上转型为 UnivMem 指针,直观上,这很合理,因为 Student 是 UnivMem 的一种。

void printMembers(UnivMem* mems[]) {for (int i = 0; mems[i] != NULL; i++)mems[i]->Print();
}
int main() {UnivMem* members[MAX_N] = { NULL };members[0] = new Student(...);members[1] = new Professor(...);printMembers(members);return 0;
}

0x05 继承和指针

如果我们使用一个 Student 指针,我们可以访问对象的所有公共属性和方法,请注意下面的图表仅为概念说明(实际上,方法不存储在对象内存中),此图中不包括私有属性。

与此同时,如果我们使用一个 UnivMem 指针,我们只能访问 UnivMem 类中的公共属性和方法, 即使实际上被这个 UnivMem 指针指向的对象是一个 Student 对象,我们也不能调用 GetGPA() 方法。

在这个例子中,只有第一个调用 s->GetGPA() 会成功编译和运行。

即使 m1 实际上指向一个 Student 对象,m1->GetGPA() 也不会编译通过。

int main() {UnivMem* m1, * m2;Student* s = new Student(...);Professor* p = new Professor(...);m1 = s;m2 = p;cout << s->GetGPA() << endl;  // OKcout << p->GetGPA() << endl;  // Errorcout << m1->GetGPA() << endl; // Errorcout << m2->GetGPA() << endl; // Errorreturn 0;
}


📌 [ 笔者 ]   王亦优
📃 [ 更新 ]   2024.6.10
❌ [ 勘误 ]   /* 暂无 */
📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,本人也很想知道这些错误,恳望读者批评指正!

📜 参考资料 

C++reference[EB/OL]. []. http://www.cplusplus.com/reference/.

Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

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

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

相关文章

PHP调用阿里云OSS的SDK封装成服务的完整指南与问题解决

在现代Web开发中&#xff0c;使用云存储来管理和存储大量的静态文件已经成为常态。阿里云OSS&#xff08;对象存储服务&#xff09;是其中一个非常受欢迎的选择。在这篇文章中&#xff0c;我们将详细讲解如何在PHP项目中集成并使用阿里云OSS SDK。 #### 一、前期准备 在开始之…

vue3轮播图怎么做

先看效果 实现代码 <n-carouseleffect"card"dot-type"line"draggable:autoplay"!isHovered":current-index"currentIndex"prev-slide-style"transform: translateX(-150%) translateZ(-450px);opacity:1"next-slide-st…

【MySQL】(基础篇十三) —— 联结

联结 本文介绍什么是联结&#xff0c;为什么要使用联结&#xff0c;如何编写使用联结的SELECT语句。介绍如何对被联结的表使用表别名和聚集函数。 SQL最强大的功能之一就是能在数据检索查询的执行中联结&#xff08;join&#xff09;表。联结是利用SQL的SELECT能执行的最重要…

springboot+vue+mybatis教师工作审核系统+PPT+论文+讲解+售后

随着社会不断进步与发展&#xff0c;生活节奏不断加快&#xff0c;信息已经成为我们生活中不可缺少的一部分&#xff0c;很多学校需要掌握大量的信息来了解特定学生的需求&#xff0c;传统的做法是组织大量的人力物力对学生散发调查表&#xff0c;然后对收集的信息进行统计并得…

基于Matlab的BP神经网络的车牌识别系统(含GUI界面)【W7】

简介&#xff1a; 本系统结合了图像处理技术和机器学习方法&#xff08;BP神经网络&#xff09;&#xff0c;能够有效地实现车牌的自动识别。通过预处理、精确定位、字符分割和神经网络识别&#xff0c;系统能够准确地识别各种车牌图像&#xff0c;并在智能交通管理、安防监控等…

LeetCode 338.比特位计数

各位朋友们&#xff0c;大家好啊&#xff0c;今天此题我用的方法比较好理解&#xff0c;但时间复杂度比较高如果大家觉得可以的话&#xff0c;不妨给个免费的赞吧&#xff0c;谢谢了^ _ ^ 1.题目要求如图所示: 2.做题步骤: 1.先计算总共多少个数: int count 0;int number 0;…

25 avl树

目录 底层结构avl树的概念节点定义插入旋转验证删除全性能 1. 底层结构 前面对map/multimap/set/multiset进行了简单的介绍&#xff0c;在其文档介绍中发现&#xff0c;这几个容器有几个共同点是&#xff1a;其底层都是按照二叉搜索树来实现的&#xff0c;但是二叉搜索树有自…

用Copilot画漫画,Luma AI生成视频:解锁创意新玩法

近年来&#xff0c;随着人工智能技术的不断发展&#xff0c;各种创意工具也层出不穷。今天&#xff0c;我们就来介绍一种全新的创作方式&#xff1a;使用Copilot画漫画&#xff0c;再将漫画放入Luma AI生成视频。 Copilot&#xff1a;你的AI绘画助手 Copilot是一款基于人工智…

使用sherpa-ncnn进行中文语音识别(ubuntu22)

获取该开源项目的渠道&#xff0c;是我在b站上&#xff0c;看到了由csukuangfj制作的一套语音识别视频。以下地址均为csukuangfj在视频中提供&#xff0c;感谢分享&#xff01; 新一代Kaldi RISC-V: VisionFive2 上的实时中英文语音识别_哔哩哔哩_bilibili 开源项目地址&…

如何将扫描的 PDF 转换为 Word

您是否正在寻找一种可靠且轻松的方式将扫描的 PDF 文档转换为可编辑的 Word 文件&#xff1f;要将 PDF 转换为可编辑的 Word 文档&#xff0c;神奇之处在于光学字符识别(OCR)。 使用 PDFgear&#xff0c;您可以无缝地将扫描的 PDF 转换为 Word&#xff0c;无论是在线还是离线。…

内网Docker镜像无法使用?Debian/Ubuntu离线安装Dokcer

离线安装Docker 卸载冲突的包 for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done先删除docker sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin d…

CLIP-guided Prototype Modulating for Few-shot Action Recognition

标题&#xff1a;基于CLIP引导的原型调制用于少样本动作识别 源文链接&#xff1a;CLIP-guided Prototype Modulating for Few-shot Action Recognition | International Journal of Computer Vision (springer.com)https://link.springer.com/article/10.1007/s11263-023-019…

awd工具安装

fscan(漏洞扫描) 下载 下载地址: Releases shadow1ng/fscan GitHub 把下载的文件放到指定文件目录里, 在文件的位置打开cmd 输入 fscan64.exe -h 192.168.1.1/24 ok了 接下来说说fscan的使用 使用 1.信息搜集: 存活探测(icmp) 端口扫描 2.爆破功能: 各类服务爆破(…

【R语言】数据可视化分析和统计检验——线性和线性混合效应模型

R语言数据可视化分析和统计检验 写在前面1、数据读取及分析2、组间均值和标准差统计分析3、图像数据探索3.1 图像绘制&#xff08;查看是否存在极端数据&#xff0c;以及数据分布情况&#xff09;3. 2 数据标准化&#xff08;Z-scores&#xff09;3.3 绘制数据相关性 4、ggplot…

Axios基础用法

目录 Axios简介&#xff1f; json-server 下载json-server 创建模拟数据json文件 运行json-server ​编辑​编辑 安装Axios Axios基础用法 创建Vue项目 get请求 post请求 put请求 delete请求 并发请求 总结 Axios简介&#xff1f; Axios是一个基于Promise的HTTP库&#xf…

ComfyUI

文章目录 一、关于 ComfyUI特点快捷键QA你为什么做这个&#xff1f;这是给谁的&#xff1f; 二、安装1、Windows直接链接下载如何在另一个UI和ComfyUI之间共享模型&#xff1f; 2、Jupyter Notebook3、手动安装&#xff08;Windows、Linux&#xff09;AMD GPU&#xff08;仅Lin…

获取wav音频文件时长部署问题

在Linux服务器上运行Java代码时&#xff0c;如果涉及到音频处理&#xff0c;可能会遇到一些在Windows上不存在的问题。尤其是在处理音频文件时&#xff0c;javax.sound.sampled.Clip接口在Linux上的兼容性可能会有问题。这是因为Clip依赖于底层的音频系统&#xff0c;而这些系统…

ubuntu搭建java开发环境IDEA版

一.安装 OpenJDK 更新包列表&#xff1a; sudo apt update安装 OpenJDK&#xff1a; 你可以选择安装不同版本的 OpenJDK&#xff0c;例如 11 或 17&#xff0c;这个是安装 OpenJDK 11 的命令&#xff1a; sudo apt install openjdk-11-jdk验证安装&#xff1a; 安装完成后…

SpringBoot实现的大文件上传

前言 大文件分片上传和断点续传是为了解决在网络传输过程中可能遇到的问题&#xff0c;以提高文件传输的效率和稳定性。 首先&#xff0c;大文件分片上传是将大文件分割成较小的片段进行上传。这样做的好处是可以减少单个文件的传输时间&#xff0c;因为较小的文件片段更容易快…

Spring AI探索

Spring AI概述 该Spring AI项目旨在简化包含人工智能功能的应用程序的开发&#xff0c;避免不必要的复杂性。 该项目从著名的 Python 项目&#xff08;例如 LangChain 和 LlamaIndex&#xff09;中汲取灵感&#xff0c;但 Spring AI 并非这些项目的直接移植。该项目的成立基于…