免费做简历的网站/如何进行网站宣传推广
文章目录
- 🦍1. 面向过程和面向对象
- 🦧2. 类的引入
- 🐶3. 类的定义
- 🦮4. 类的访问控制和封装
- 🍖4.1 访问限定符
- 🍖4.2 封装
- 🐩5. 类的作用域
- 🐅6. 类的实例化
- 🐄7. 类的大小计算
- 🦌8. this指针
- 🥕8.1 引子
- 🥕8.2 this指针特性
🦍1. 面向过程和面向对象
C语言是一门面向过程的编程语言,面向过程更注重于解决问题的步骤和流程。而C++是基于面向对象的,关注的是对象之间的交互,。我们将数据和相关的功能封装在一起,形成对象。每个对象都有自己的属性(数据)和方法(功能)。
以做一道青椒肉丝来说
我们需要厨师、青椒、肉丝、锅、铲、油、盐、老抽等物品,然后再准备烹饪。先放油,油热再放肉丝,肉丝炒的差不多之后再放青椒,然后再放入盐、老抽,最后装盘,这些就属于面向过程;
在面向对象编程中,我们会将青椒肉丝看作一个对象,并定义该对象的属性和方法。
对象:青椒肉丝
- 属性:青椒、肉片、调味料等
- 方法:准备食材、炒菜、调味、出锅等
我们可以创建一个青椒肉丝对象,并调用对象的方法来完成烹饪过程。每个方法内部可以封装相应的逻辑和操作。
例如,调用青椒肉丝对象的"准备食材"方法,内部会包含切青椒、切肉片和腌制肉片的操作。调用"炒菜"方法时,内部会进行炒肉片和炒青椒的步骤。通过调用对象的方法,我们可以按照特定的顺序和逻辑来完成整个烹饪过程。
面向过程适用于简单的、直线式的问题,或者强调步骤和算法的场景。面向对象适用于复杂的、需要模拟真实世界的问题,或者强调对象之间关系和交互的场景。现在市面上主流的编程语言基本上都是面向对象:C++、Java、Python等。
🦧2. 类的引入
在C语言中,结构体就可以封装多个对象用来描述一些负责的事物。在C++中,将结构体升级成了类,不仅可以定义变量,还可以定义函数。
struct Stack
{//方法(函数)void Init(int defaultCapacity = 4){a = (int*)malloc(sizeof(int) * 4);if (nullptr == a){perror("malloc fail");exit(-1);}capacity = defaultCapacity;top = 0;}void Push(int x){//...;}void Destory(){free(a);a = nullptr;top = capacity;}//...//成员变量(属性)int* a;int top;int capacity;
};
int main()
{//兼容C语言struct Stack s1;//C++Stack st2;st2.Init();st2.Push(1);st2.Push(2);st2.Destory();return 0;
}
🐶3. 类的定义
虽然struct
可以定义类,但是为了区分C语言,C++更喜欢用class
来定义类。
class
定义为类的关键字,后面紧跟类名,{}
为类的主体。
class ClassName {
private:// 成员变量(私有)DataType memberVariable1;DataType memberVariable2;...public:// 构造函数ClassName(); // 默认构造函数ClassName(parameter1, parameter2, ...); // 带参数的构造函数// 成员函数(公有)ReturnType memberFunction1(parameter1, parameter2, ...);ReturnType memberFunction2(parameter1, parameter2, ...);...
};
- 使用
class
关键字来定义类,后面紧跟着类名(通常遵循命名约定,使用驼峰命名法)。 - 在类定义中,我们可以声明成员变量和成员函数。
- 成员变量是类的数据成员,表示类的特征或状态。它们在私有部分(
private
)进行声明,只能在类的内部访问。 - 构造函数是一种特殊的成员函数,用于创建和初始化类的对象。在示例中,我们展示了默认构造函数和带参数的构造函数的定义。构造函数的名称与类名相同,没有返回类型。
- 成员函数是类的行为和操作。它们在公有部分(
public
)进行声明,并可以包含任意的参数和返回类型。成员函数可以访问类的成员变量,执行特定的操作。
类也可以声明和定义分离:
类里面定义的函数,默认是内联函数,但具体也还是编译器决定是否为内联函数。
🦮4. 类的访问控制和封装
🍖4.1 访问限定符
当使用class
来定义时,程序编译报错,我们定义的这些方法,无法访问。
这些是因为C++中类进行了封装和访问控制,用三种修饰符来实现:
private
(私有): 成员被声明为private
时,它们只能在类的内部访问。私有成员对于类的外部是不可见的,外部代码无法直接访问它们。public
(公有): 成员被声明为public
时,它们可以在类的内部和外部被访问。公有成员对外部代码可见,可以通过类的对象访问和操作。protected
(保护): 成员被声明为protected
时,它们与私有成员类似,只能在类的内部和派生类中访问。受保护成员对于外部代码是不可见的,但可以在派生类中被继承和访问。
访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。
class
如果不设置访问限定符,默认为private
;
struct
因为要兼容C语言,所以默认为public
。
🍖4.2 封装
面向对象的三大特性:封装、继承、多态。
在面向对象的封装中,类是封装的基本单位,类封装了数据成员和成员函数。封装的主要目的是将相关的数据和操作组织在一起,形成一个独立的实体,对外部隐藏其内部实现细节,只提供公共接口。
比如说,我们国家的博物馆里面的展品,大部分都会设置阻隔,我们观众可以参观,但是无法直接接触到这些展品。这在一定程度上保护了这些展品,同时也规范了观众的行为,满足了观众的基本需求。
在程序中,封装也是如此,通过将数据和操作封装在一起,实现了数据的隐藏和保护。
🐩5. 类的作用域
类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 ::
作用域操作符指明成员属于哪个类域
class MyClass {
public:int publicMember; // 公有成员void PrintInfo();
private:int privateMember; // 私有成员protected:int protectedMember; // 受保护成员
};//指定PrintInfor属于MyClass这个类域
void MyClass::PrintInfo()
{cout << "MyClass" << endl;
}int main() {MyClass myObject;myObject.publicMember = 10; // 可访问公有成员myObject.PrintInfo();// 以下代码将导致编译错误,无法访问私有成员和受保护成员// myObject.privateMember = 20;// myObject.protectedMember = 30;return 0;
}
🐅6. 类的实例化
类的实例化是指根据类的定义创建一个具体的对象,使其具备类所定义的属性和行为。
我们定义一个类:
class Person
{
public:void showInfo(){cout << "xxx" << endl;//...}
private:char* _name;char* _sex;int _age;
};
这里并没有实例化↑,只是描述出了一个人应该具备的基本属性。
//直接声明对象变量静态实例化对象
Person P1;Person P2;
实例化对象 ↑ P1、P2。
类就好比一张食谱,食谱上面有许多道菜的做法,但没有实际的菜存在,所以定义出一个类并没有分配实际的内存空间来存储它。
我们将其实例化,就是把这道菜做出来呈现在我们眼前,它实际存在,占据物理空间。
🐄7. 类的大小计算
class MyClass
{
public:void Print(){cout << "MyClass" << endl;}
private:int a;
};int main()
{cout << sizeof(MyClass) << endl;return 0;
}
类中既有成员变量,又有成员函数,那么这在计算内存的时候,是如何计算的呢?
// 类中既有成员变量,又有成员函数
class A1 {
public:void f1() {}
private:int _a;
};// 类中仅有成员函数
class A2 {
public:void f2() {}
};// 类中什么都没有---空类
class A3
{};int main()
{cout << sizeof(A1) << endl;cout << sizeof(A2) << endl;cout << sizeof(A3) << endl;
}
执行该程序得出:
4
1
1
我们发现,类的大小,计算的是该类中的成员变量之和,并没有算入函数;而没有成员变量或者是空类,大小为1byte。
这是因为成员函数是共享给所以该类的使用对象使用的代码,并不直接存储在该类中。
打个比方:
假设我们有一个小区,里面有很多房屋,每个房屋都有自己的卧室、客厅、厨房等空间,这些就代表着类对象中的数据成员。
但是小区里面会有公共的篮球场、公园等空间,这些并没有算在自己房子的大小之内,属于公共区域,供小区居民共享使用的。
在这个比喻中,房屋可以类比为类对象的数据成员,而篮球场可以类比为类的成员函数。房屋占用实际的空间,我们说房子多大就是自己的房子有多少个平方,而篮球场作为公共设施,只是为小区居民提供服务,不会计算在房子的大小中。
类成员计算大小时,也遵循内存对齐规则——内存对齐。
🦌8. this指针
🥕8.1 引子
我们定义一个人的类Person
class Person
{
public:void Init(const std::string& n, const std::string& sex, int age){_name = n;_sex = sex;_age = age;}void Print(){cout << _name << " " << _sex << " " << _age << endl;}
private:std::string _name;std::string _sex;int _age = 0;
};int main()
{Person p1, p2;p1.Init("zhangsan", "man", 21);p2.Init("cuihua", "woman", 20);p1.Print();p2.Print();
}
Person
类中,有Init
和Print
两个成员函数,我们刚才说到,成员函数并没有算入类的空间中,那当p1
调用Init
和Print
的时候,这两个函数是怎么知道是p1
呢?
C++中,给每个非静态成员函数,增加了一个隐藏的指针参数,该指针指向了当前对象,函数体的所以成员变量的操作都是通过指针去访问的。这个对于我们用户来说是透明的,不需要我们来传递,编译器自动完成。
🥕8.2 this指针特性
-
只能在成员函数内部使用
-
this
指针是成员函数的第一个隐藏指针形参,由编译器自动传递由于
this
指针是一个形参,所以应该就和普通的参数一样存放在栈区里面,但是有些编译器会对其进行优化。以VS2022为例,我们发现
this
指针存放在了rcx
中(rcx是x86架构中通用的寄存器之一)。 -
this
指针是一个常量指针,它指向当前对象并不能被修改,也不能被显式地赋值给其他指针变量。它始终指向当前对象,无法指向其他对象。
有了这些知识储备,我们来看一下,这段程序的运行结果是什么?
class A
{
public:void PrintA(){cout << "PrintA()" << endl;}
private:int _a;
};
class B
{
public:void PrintB(){cout << _b << endl;}
private:int _b;
};
int main()
{A* pa = nullptr;B* pb = nullptr;pa->PrintA();pb->PrintB();return 0;
}
运行发现,控制台上打印出了PrintA()
,随后程序运行崩溃了。
这是因为A和B在调用各自的Print()
成员函数时,没有发生解引用,因为Print()
的地址不在对象中,A和B作为实参传递给了this
指针。但是进入Print()
函数后,由于A和B都是空,所以this
指针也为空,A没有对齐解引用,而B访问了它的成员_b
,本质上就是this->_b
,对空指针解引用,所以会崩溃。
我们需要知道类是面向对象编程的核心概念,类是对象的蓝图,定义了对象的属性和行为,而对象则是根据类的定义创建的实体。
那本期的分享就到这里啦,如果有帮助的话,希望三连支持一下,我们下期再见,如果还有下期的话。
相关文章:

C++类和对象(上)
文章目录 🦍1. 面向过程和面向对象🦧2. 类的引入🐶3. 类的定义🦮4. 类的访问控制和封装🍖4.1 访问限定符🍖4.2 封装 🐩5. 类的作用域🐅6. 类的实例化🐄7. 类的大小计算&a…...

JavaScript 数据透视表 DHTMLX Pivot Crack
DHTMLX Pivot JavaScript 数据透视表 - 强大的数据汇总和报告 使用我们的高速 JavaScript/HTML5 Pivot 组件可视化您的复杂数据,从而提高您的商业智能。 它可以帮助您以方便的方式汇总大型数据集。 主要特征 纯 JavaScript 库,可轻松与任何服务器端集成…...

QT链接库设置
以windows 平台为例,在.pro 文件中: 1 增加 INCLUDEPATH <头文件路径> DEPENDPATH <头文件路径> 2 LIBS -L<库目录路径> -l<库得名字> 3 设置MT、MTD、MD、MDD运行时库 win32:CONFIG(debug, debug|release): { QMAKE_CFLAGS_…...

零点起飞学Android——期末考试课本复习重点
目录 第一章 认识Android第二章 Android常见界面布局第三章 Android常用基本控件第四章 Android 高级控件第五章 Android菜单和对话框 第一章 认识Android 1. Android 界面设计被称为______。 答案:布局 2. Android中常见的布局包括______、______ 、______ 、____…...

Redis为什么快?
目录 Redis为什么快?渐进式ReHash全局哈希表渐进式ReHash 缓存时间戳 Redis为什么快? 纯内存访问; 单线程避免上下文切换; 渐进式ReHash、缓存时间戳; 前面两个都比较好理解,下面我们主要来说下 渐进式…...

Zabbix从入门到精通以及案例实操系列
1、Zabbix入门 1.1、Zabbix概述 Zabbix是一款能够监控各种网络参数以及服务器健康性和完整性的软件。Zabbix使用灵活的通知机制,允许用户为几乎任何事件配置基于邮件的告警。这样可以快速反馈服务器的问题。基于已存储的数据,Zabbix提供了出色的报告和…...

水声声波频率如何划分?水声功率放大器可将频率放大到20MHz吗?
水声声波频率如何划分?水声功率放大器可将频率放大到20MHz吗? 现如今我们可以在地球任意地区实现通信,是因为电磁波的作用。但是我们都知道海洋占了全球十分之七面积,电磁波在水下衰减速度太快,无法做到远距离传输&am…...

网络攻防技术--论文阅读--《基于自动数据分割和注意力LSTM-CNN的准周期时间序列异常检测》
英文题目:Anomaly Detection in Quasi-Periodic Time Series based on Automatic Data Segmentation and Attentional LSTM-CNN 论文地址:Anomaly Detection in Quasi-Periodic Time Series Based on Automatic Data Segmentation and Attentional LST…...

C++ 学习 ::【基础篇:08】:C++ 中 struct 结构体的认识【面试考点:C 与 C++ 中结构体的区别】
本系列 C 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C 学习系列将分为三个阶段:基础篇、STL 篇、高阶数据结构与算法篇,相关重点内容如下: 基础篇:类与对象(涉及C的三大特性等&#…...

Electron开发:打包和发布 Electron 应用
https://start.spring.io/ 在线数据分析网站 https://tj.aldwx.com/ https://www.spsspro.com/ win10如何分屏 拖到边缘 Electron 环境搭建 https://www.electronjs.org/zh/docs/latest/tutorial/%E6%89%93%E5%8C%85%E6%95%99%E7%A8%8B electron 隐藏菜单 electron 标题栏 设…...

【每日一题Day222】LC1110删点成林 | dfs后序
删点成林【LC1110】 给出二叉树的根节点 root,树上每个节点都有一个不同的值。 如果节点值在 to_delete 中出现,我们就把该节点从树上删去,最后得到一个森林(一些不相交的树构成的集合)。 返回森林中的每棵树。你可以按…...

[ChatGPT] 从 GPT-3.5 到 GPT-5 的进化之路 | ChatGPT和程序员 : 协作 or 取代
⭐作者介绍:大二本科网络工程专业在读,持续学习Java,努力输出优质文章 ⭐作者主页:逐梦苍穹 ⭐如果觉得文章写的不错,欢迎点个关注一键三连😉有写的不好的地方也欢迎指正,一同进步😁…...

6.4 GDP调试多进程程序
目录 GDB调试多进程程序 安装gdb gdb编译 运行gdb 单步运行 从头到尾运行 下一步 运行子进程 同时运行父进程 查看运行的进程 切换进程 退出 GDB调试多进程程序 set follow-fork-mode child 设置GDB调试子进程 set follow-fork-mode parent 设置GDB调试父进…...

TDengine 时序数据的保留策略
“TDengine除vnode分片之外,还对时序数据按照时间段进行分区。每个数据文件只包含一个时间段的时序数据,时间段的长度由DB的配置参数days决定。这种按时间段分区的方法还便于高效实现数据的保留策略,只要数据文件超过规定的天数(系…...

Java-多线程解析1
一、线程的描述: 1、线程是一个应用程序进程中不同的执行路径比例如:一个WEB服务器,能够为多个用户同时提供请求服务;而 -> 进程是操作系统中正在执行的不同的应用程序,比如:我们可以同时打开系统的word和游戏 2、多…...

PHP 判断用户当前坐标是否在电子围栏内
可以使用射线法判断用户当前坐标点是否在电子围栏内。 具体步骤如下: 1. 将电子围栏的四个角坐标按顺序连接成一个封闭多边形。 2. 从用户当前坐标点向外发射一条射线,判断这条射线与多边形的交点个数。 3. 如果交点个数为奇数,则用户当前…...

Java版本工程管理系统源码企业工程项目管理系统简介
一、立项管理 1、招标立项申请 功能点:招标类项目立项申请入口,用户可以保存为草稿,提交。 2、非招标立项申请 功能点:非招标立项申请入口、用户可以保存为草稿、提交。 3、采购立项列表 功能点:对草稿进行编辑&#x…...

高速缓存(cache)的原理: 了解计算机架构与性能优化
计基之存储器层次结构 Author: Once Day Date: 2023年5月9日 长路漫漫,而今才刚刚启程! 本内容收集整理于《深入理解计算机系统》一书。 参看文档: 捋一捋Cache - 知乎 (zhihu.com)iCache和dCache一致性 - 知乎 (zhihu.com)C…...

【Vue3+TS项目】硅谷甄选day04--顶部组件搭建+面包屑+路由鉴权
顶部组件搭建 顶部左侧折叠和面包屑实现 左侧菜单刷新折叠的问题解决---属性default-active 折叠之后图标不见:icon放在插槽外面----element的menu属性:collapse project\src\layout\index.vue // 获取路由对象 import { useRoute } from vue-route…...

某oa 11.10 未授权任意文件上传
漏洞简介 之前也对通达 oa 做过比较具体的分析和漏洞挖掘,前几天看到通达 oa 11.10 存在未授权任意文件上传漏洞,于是也打算对此进行复现和分析。 环境搭建 https://www.tongda2000.com/download/p2019.php 下载地址 :https://cdndown.tongda…...

Grounded Language-Image Pre-training(论文翻译)
文章目录 Grounded Language-Image Pre-training摘要1.介绍2.相关工作3.方法3.1统一构建3.2.语言感知深度融合3.3.使用可扩展的语义丰富数据进行预训练 4.迁移到既定的基准4.1.COCO上的zero-shot和监督迁移学习4.2.LVIS上的zero-shot 迁移学习4.3.Flickr30K实体上的 phrase gro…...

设计模式-行为型模式(模板方法、策略、观察者、迭代器、责任链、命令、状态、备忘录、访问者、中介者、解释器)
行为型模式:专注于对象之间的 协作 及如何通过彼此之间的交互来完成任务。行为型模式通常集中在描述对象之间的 责任 分配和 通信 机制,并提供了一些优雅解决特定问题的方案。 模板方法模式(Template Method Pattern)策略模式(Strategy Pattern)观察者模…...

全面探讨 Spring Boot 的自动装配机制
Spring Boot 是一个基于 Spring 框架的快速开发脚手架,它通过自动配置机制帮助我们快速搭建应用程序,从而减少了我们的配置量和开发成本。自动装配是 Spring Boot 的核心特点之一,它可以减少项目的依赖,简化配置文件,提…...

河道水位监测:河道水位监测用什么设备
中国地形复杂,气候多样,导致水资源分布不均,洪涝和干旱等问题时有发生。同时,人类活动也对水资源造成了很大压力,工业和农业用水增加,河道水位下降,生态环境受到威胁。因此,对河道水…...

嵌入式系统中u-boot和bootloader到底有什么区别
嵌入式软件工程师都听说过 u-boot 和 bootloader,但很多工程师依然不知道他们到底是啥。 今天就来简单讲讲 u-boot 和 bootloader 的内容以及区别。 Bootloader Bootloader从字面上来看就是启动加载的意思。用过电脑的都知道,windows开机时会首先加载…...

实验14:20211030 1+X 中级实操考试(id:2498)
实验14:20211030 1X 中级实操考试(id:2498) 一、项目背景说明二、表结构三、步骤【5 分】步骤 1:项目准备【5 分】步骤 2:完成实体类 Member【10 分】步骤 3:完成实体类 Goods【10 分】步骤 4&a…...

(字符串 ) 剑指 Offer 58 - II. 左旋转字符串 ——【Leetcode每日一题】
❓剑指 Offer 58 - II. 左旋转字符串 难度:简单 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的…...

EPICS编程
提纲 1) 为什么在EPICS上编程 2)构建系统特性:假设基本理解Unix Make 3)在libCom中可用的工具 1) 为什么在EPICS上编程 1、社区标准:EPICS合作者知道和明白EPICS结构 2、在很多操作系统之间代码移值性…...

17:00面试,还没10分钟就出来了,问的实在是太...
从外包出来,没想到死在另一家厂子 自从加入这家公司,每天都在加班,钱倒是给的不少,所以也就忍了。没想到8月一纸通知,所有人不许加班,薪资直降30%,顿时有吃不起饭的赶脚。 好在有个兄弟内推我去…...

docker都有那些工具,及工具面试题
docker介绍 Docker 是一种开源的容器化平台,可以帮助开发者将应用程序和依赖项打包到轻量级的容器中,然后部署到任何基于 Linux 的操作系统中。使用 Docker 可以大大简化开发、部署和管理应用程序的过程,使其更加快速、灵活和可靠。 Docker…...