当前位置: 首页 > news >正文

C++笔记---类和对象

1. 类的定义

类是C++中的一种自定义类型,是某个具体事物或概念的抽象化代码表示,通过类的成员(变量+函数/方法),可以表征出事物或概念的特征。

1.1 类定义的格式

class Stack
{
public:// 成员函数void Init(int n = 4){array = (int*)malloc(sizeof(int) * n);if (nullptr == array){perror("malloc申请空间失败");return;}capacity = n;top = 0;}void Push(int x){// ...扩容array[top++] = x;}int Top(){assert(top > 0);return array[top - 1];}void Destroy(){free(array);array = nullptr;top = capacity = 0;}
private:// 成员变量int* array;size_t capacity;size_t top;
}; // 分号不能省略

class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省 略。类和C语言中的结构体类似,类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数/类函数。一般来说,这些类函数是专门设计来服务于这个类类型的变量(对象)。

为了区分成员变量,一般习惯上成员变量会加一个特殊标识,如成员变量前面或者后面加_ 或者 m 开头,注意C++中这个并不是强制的,只是一些惯例,具体看公司的要求。

// _成员变量名
int* _array;
size_t _capacity;
size_t _top;// 成员变量名_
int* array_;
size_t capacity_;
size_t top_;// m成员变量名
int* mArray;
size_t mCapacity;
size_t mTop;

C++中struct也可以定义类,C++兼容C中struct的用法,同时struct升级成了类,明显的变化是 struct中可以定义函数,一般情况下我们还是推荐用class定义类。

定义在类中的成员函数默认为inline。

1.2 访问限定符

上面Stack类中的“public”和“private”就是访问限定符,除此之外,还有“protected”。

他们的作用是限定类成员被访问的权限。

• C++一种实现封装的方式,用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。

• public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问,protected和private是一样的,以后继承章节才能体现出他们的区别。

• 访问权限作用域从该访问限定符出现的位置开始直到下⼀个访问限定符出现时为止,如果后面没有访问限定符,作用域就到 “}”即类结束。

• class定义成员没有被访问限定符修饰时默认为private,struct默认为public。

• 一般成员变量都会被限制为private/protected,需要给别人使用的成员函数会放为public。

习惯上,被public修饰的成员统一放到前面,被private修饰的成员统一放到后面。

被public修饰的一般是类函数,被private修饰的一般是成员变量。

1.3 类域

类定义了一个新的作用域,类的所有成员都在类的作用域中,在类体外定义成员时,需要使用 :: 作 用域操作符指明成员属于哪个类域。

前面提到,在类中定义的函数默认为inline函数,如果不希望某个函数被当作inline函数,则可将类函数的声明与定义分开,只在类中声明,而在类外进行定义。

class Stack
{
public:// 成员函数void Init(int n = 4);void Push(int x);int Top();void Destroy();
private:// 成员变量int* array;size_t capacity;size_t top;
}; // 分号不能省略void Stack::Init(int n = 4)
{array = (int*)malloc(sizeof(int) * n);if (nullptr == array){perror("malloc申请空间失败");return;}capacity = n;top = 0;
}
void Stack::Push(int x)
{// ...扩容array[top++] = x;
}
int Stack::Top()
{assert(top > 0);return array[top - 1];
}
void Stack::Destroy()
{free(array);array = nullptr;top = capacity = 0;
}

类域影响的是编译的查找规则,上面程序中的函数如果不指定类域Stack,那么编译器就把这些函数当成全局函数,那么编译时,找不到array等成员的声明/定义在哪里,就会报错。指定类域Stack,就是知道这些函数是成员函数,当前域找不到的array等成员,就会到类域中去查找。

2. 对象的定义(实例化)

简单来说,类只是一种类似于结构体的类型,用类类型定义出的变量,就是该类的对象。

2.1 实例化的概念

用类类型在物理内存中创建对象的过程,称为类实例化出对象。

类是对象进行的一种抽象描述,是一个模型一样的东西,限定了类有哪些成员变量,这些成员变量只是声明,没有分配空间,用类实例化出对象时,才会分配空间。

一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量。打个比方:类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,设计图规划了有多 少个房间,房间大小功能等,但是并没有实体的建筑存在,也不能住人,用设计图修建出房子,房 子才能住人。同样类就像设计图一样,不能存储数据,实例化出的对象分配物理内存存储数据。

以“Date类”为例:

class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}
private:// 这⾥只是声明,没有开空间int _year;int _month;int _day;
};

这里给出了定义“Date类”类型变量的蓝图,利用该类进行实例化,就可以得到“Date类”类型的变量。

int main()
{// Date类实例化出对象day1和day2Date day1;Date day2;return 0;
}

2.2 this指针

相信读者已经注意到,类函数看上去似乎有些奇怪:这些函数直接使用了类中的成员变量,而没有对应形参的传入,那么这些函数怎么知道成员变量是谁的呢?。

我们从类函数的调用方式入手:

int main()
{Date day1;day1.print(2024, 7, 29);Date day2;day2.print(2004, 12, 18);return 0;
}

因为类函数也是类的成员,所以使用成员访问操作符“.”访问对象的成员即可调用类函数。

可以看到,类函数的调用是与某个对象绑定在一起的,所以类函数能知道成员变量是哪个对象的。

但是,在底层上是如何做到的呢?

编译器编译后,类的成员函数默认都会在形参第一个位置,增加一个当前类类型的指针,叫做“this指针”。比如Date类的Init的真实原型为: 

void Init(Date* const this, int year, int month, int day);

所以,在调用类函数时,当前对象的地址就会通过“this指针”传入函数中,函数就能对该对象的成员变量进行操作。

类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_year赋值的语句相当于是:

 this->_year = year;

2.3 对象的大小

我们已经了解过C语言中结构体的大小C语言结构体的大小,结构体内存对齐_c语言 struct大小-CSDN博客

相比于结构体,类增加了成员函数,那么这些成员函数会使实例化出的对象的空间如何变化呢?

对于同一个类,不同的对象之间成员变量一般不同,但是成员函数完全相同。所以,没有单独为每一个对象存储成员函数的必要。其次,函数被编译后是一段指令,对象中没办法存储,这些指令 存储在一个单独的区域(代码段),那么对象中非要存储的话,也只能是成员函数的指针。同一个函数只有一个地址,也没有必要分别存储。最后,其实函数指针本身就是不需要存储的,函数指针是一个地址,调用函数被编译成汇编指令[call 地址], 其实编译器在编译链接时,就要找到函数的地址,不是在运行时找,只有动态多态是在运行时找,就需要存储函数地址,这个我们以后会讲解。

总结来说,每个类的对象的大小只与成员变量有关,成员函数不存储在对象中。在此基础上,符合内存对齐的原则。

相关文章:

C++笔记---类和对象

1. 类的定义 类是C中的一种自定义类型&#xff0c;是某个具体事物或概念的抽象化代码表示&#xff0c;通过类的成员&#xff08;变量函数/方法&#xff09;&#xff0c;可以表征出事物或概念的特征。 1.1 类定义的格式 class Stack { public:// 成员函数void Init(int n 4)…...

全国区块链职业技能大赛样题第9套后端源码

后端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746050 前端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746216 智能合约+数据库表设计:https://blog.csdn.net/Qhx20040819/article/details/140746646 项目预览 登录 用户管理...

3个功能强大的PDF转换工具,免费试用

给大家分享3个功能强大能满足更高需求的PDF转换工具&#xff0c;都提供免费的试用机会。 1.嗨动PDF编辑器 一款多功能的PDF编辑软件&#xff0c;集PDF阅读、PDF转换、PDF编辑功能为一体。支持转换的格式多样&#xff0c;转换速度快&#xff0c;转换后的排版和内容与原文保持一…...

表单修改数字输入框保留小数点

1.在表单设计打开修改的表单 2.打开需要修改的字段 3.按F12&#xff0c;进入“开发模式” 4.开启“开发者工具”左上角检索工具 开启&#xff1a;鼠标左键点击&#xff0c;当图标颜色为蓝色 关闭&#xff1a;鼠标左键点击&#xff0c;当图标颜色为灰色 5.鼠标移动到需要修改的…...

[VS Code扩展]写一个代码片段管理插件(一):介绍与界面搭建

文章目录 VS Code扩展机制项目搭建创建UI元素活动栏按钮主边栏视图主边栏工具栏按钮侧边栏右键菜单编辑器右键菜单 项目地址 [VS Code扩展]写一个代码片段管理插件&#xff08;一&#xff09;&#xff1a;介绍与界面搭建[VS Code扩展]写一个代码片段管理插件&#xff08;二&…...

vxe grid slots 用法

官方例子&#xff1a;Vxe Table v3.8 {field: num1,title: Num1,showHeaderOverflow: true,filters: [{ data: }],editRender: { autofocus: .my-input },slots: {// 使用插槽模板渲染default: num1_default,header: num1_header,footer: num1_footer,filter: num1_filter,edi…...

【网络】基于UDP协议的聊天室(第二篇)

目录 UDP服务器 UDP客户端 在C中&#xff0c;使用UDP协议进行网络通信通常涉及到socket编程。下面我将给出基于UDP的简单的客户端和服务器示例代码。这些示例将使用C标准库以及POSIX套接字接口&#xff08;主要适用于Linux和类Unix系统&#xff09;。如果你在使用Windows&…...

【SpringBoot3】场景整合(实战)

0 环境准备 0.0 云服务器 阿里云、腾讯云、华为云 服务器开通&#xff1b; 按量付费&#xff0c;省钱省心 安装以下组件&#xff1a;docker、redis、kafka、prometheus、grafana 下载windterm&#xff1a; https://github.com/kingToolbox/WindTerm/releases/download/2.5…...

【全网最全最详细】MYSQL 面试题大全(上)

目录 一、关系型数据库和非关系型数据库主要有哪些区别? 二、MYSQL的数据存储一定是基于硬盘的吗? 三、InnoDB和MyISAM有什么区别? 四、MyISAM的索引结构是怎么样的?存在的问题是什么? 五、char和varchar的区别? 六、MYSQL 5.x和8.0有什么区别? 七、为什么大厂不…...

【C语言】程序环境,预处理,编译,汇编,链接详细介绍,其中预处理阶段重点讲解

目录 程序环境 翻译环境 1. 翻译环境的两个过程 2. 编译过程的三个阶段 执行环境 预处理(预编译) 1. 预定义符号 2. #define 2.1 用 #define 定义标识符(符号) 2.2 用 #define 定义宏 2.3 #define 的替换规则 2.4 # 和 ## 的用法 2.5 宏和函数 2.6 #undef …...

人生低谷来撸C#--021 多线程

1、概念 线程 被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作&#xff0c;那么设置不同的线程执行路径往往是有益的&#xff0c;每个线程执行特定的工作。 线程是轻量级进程。一个使用线程的常见实例是现代操作系统中…...

【优秀python django系统案例】基于python的医院挂号管理系统,角色包括医生、患者、管理员三种

随着信息技术的迅猛发展&#xff0c;传统的医院挂号管理方式面临着效率低下、排队时间长、信息不对称等诸多问题。这些问题不仅影响患者的就医体验&#xff0c;也加重了医院工作人员的负担。在此背景下&#xff0c;基于Python的医院挂号管理系统应运而生。该系统旨在通过信息化…...

硬盘数据丢失不再怕,四大恢复工具帮你轻松逆转局面!

硬盘故障、误删文件、病毒攻击等原因导致数据丢失的情况时有发生。面对这种情况&#xff0c;如何高效、快速地进行硬盘数据恢复呢&#xff1f;接下来几款好用的数据恢复软件推荐给大家。 一、福昕数据恢复&#xff1a;全方位恢复&#xff0c;让数据无遗漏 链接&#xff1a;ww…...

自定义封装日历组件

自定义日历 工作需要&#xff0c;但现有框架封装的日历无法满足需求&#xff0c;又找不到更好的插件&#xff0c;所以准备自己封装一个。 效果图和说明 一个很简易版的demo日历&#xff0c;本文只提供最基本的功能代码&#xff0c;便于阅读二开。 新建calendar.vue文件 <…...

【大模型】【面试】独家总结表格

问题解答你能解释一下Transformer架构及其在大型语言模型中的作用吗?Transformer架构是一种深度神经网络架构,于2017年由Vaswani等人在他们的论文“Attention is All You Need”中首次提出。自那以后,它已成为大型语言模型(如BERT和GPT)最常用的架构。 Transformer架构使用…...

C# 6.定时器 timer

使用控件&#xff1a; 开启定时器&#xff1a;timer1.Start(); 关闭定时器&#xff1a;timer1.Stop(); 定时间时间间隔:Interval timer1.Interval 1000; Interva等于1000是每一秒刷新一次 定时器默认时间间隔是100ms 代码创建定时器 ①创建 Timer t1 new Timer(); …...

有了 createSlice,还有必要使用 createReducer 吗?什么情况需要 createReducer 呢?

通常情况下&#xff0c;使用 createSlice 已经足够满足大多数需求&#xff0c;而不需要直接使用 createReducer。但是&#xff0c;在某些特定场景下&#xff0c;createReducer 仍然有其用处&#xff1a; 更细粒度的控制&#xff1a; 当你需要对 reducer 的行为进行更精细的控制…...

怎么搭建AI带货直播间生成虚拟主播?

随着电商直播带货的热潮不断升温&#xff0c;虚拟主播逐渐崭露头角&#xff0c;成为电商直播领域的新宠&#xff0c;相较于真人主播&#xff0c;虚拟主播具备无档期风险、人设稳定可控、24小时不间断直播等显著优势。 本文将深入探讨如何搭建一个AI带货直播间&#xff0c;并详…...

设计模式的原则

设计模式的原则通常包括以下几种核心原则&#xff1a; 单一职责原则 (SRP)&#xff1a;一个类应该只有一个单一的职责&#xff0c;即该类应该只有一个引起它变化的原因。这样可以减少类之间的耦合&#xff0c;使得系统更加易于维护和扩展。 开放/封闭原则 (OCP)&#xff1a;软…...

RocketMQ与RabbitMQ的区别:技术选型指南

在现代分布式系统和微服务架构中&#xff0c;消息队列&#xff08;Message Queue&#xff0c;简称MQ&#xff09;扮演着至关重要的角色。消息队列用于实现系统间的异步通信、解耦、削峰填谷等功能。目前常见的MQ实现包括ActiveMQ、RabbitMQ、RocketMQ和Kafka。本文将重点对比Ro…...

小白也能懂:SQL注入攻击基础与防护指南

SQL注入是一种针对数据库的攻击方式&#xff0c;攻击者通过在Web表单、URL参数或其他用户输入的地方插入恶意SQL代码&#xff0c;以此绕过应用程序的验证机制&#xff0c;直接与后台数据库交互。这种攻击可以导致攻击者无授权地查看、修改或删除数据库中的数据&#xff0c;甚至…...

【Hot100】LeetCode—76. 最小覆盖子串

题目 原题链接&#xff1a;76. 最小覆盖子串 1- 思路 利用两个哈希表解决分为 &#xff1a;① 初始化哈希表、②遍历 s&#xff0c;处理当前元素&#xff0c;判断当前字符是否有效、③收缩窗口、④更新最小覆盖子串 2- 实现 ⭐76. 最小覆盖子串——题解思路 class Solution …...

删除排序链表中的重复元素 II(LeetCode)

题目 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 解题 class ListNode:def __init__(self, val0, nextNone):self.val valself.next nextclass Solution:def deleteDuplicates(self…...

【Java】解决如何将Http转为Https加密输出

目录 HTTP转HTTPS一、 获取 SSL/TLS 证书二、 安装证书2.1 Apache2.2 Nginx 三、更新网站配置四. 更新网站链接五. 检查并测试六. 自动续期&#xff08;针对 Lets Encrypt&#xff09; HTTP转HTTPS 将网站从 HTTP 转换为 HTTPS 能够加密数据传输&#xff0c;还能提高搜索引擎排…...

二叉树链式结构的实现(递归的暴力美学!!)

前言 Hello,小伙伴们。你们的作者菌又回来了&#xff0c;前些时间我们刚学习完二叉树的顺序结构&#xff0c;今天我们就趁热打铁&#xff0c;继续我们二叉树链式结构的学习。我们上期有提到&#xff0c;二叉树的的底层结构可以选为数组和链表&#xff0c;顺序结构我们选用的数…...

Python | Leetcode Python题解之第312题戳气球

题目&#xff1a; 题解&#xff1a; class Solution:def maxCoins(self, nums: List[int]) -> int:n len(nums)rec [[0] * (n 2) for _ in range(n 2)]val [1] nums [1]for i in range(n - 1, -1, -1):for j in range(i 2, n 2):for k in range(i 1, j):total v…...

远程访问mysql数据库的正确打开方式

为了安全&#xff0c;mysql数据库默认只能本机登录&#xff0c;但是在有些时候&#xff0c;我们会有远程登录mysql数据库的需求&#xff0c;这时候应该怎么办呢&#xff1f; 远程访问mysql数据&#xff0c;需要两个条件&#xff1a; 首先需要mysql服务器将服务绑定到0.0.0.0…...

网络6 -- udp_socket 实现 echo服务器

目录 1.server 服务端 1.1.完整代码展示&#xff1a; 1.2.代码解析&#xff1a; 1.2.1 给服务端创建套接字 1.2.2 绑定套接字 1.2.3 服务端接受数据并返回 2.客户端&#xff1a; 2.1 完整代码展示&#xff1a; 2.2 代码解析 2.2.1 客户端使用手则&#xff1a; 2.2.2 …...

ASUS/华硕幻15 2020 冰刃4 GX502L GU502L系列 原厂win10系统 工厂文件 带F12 ASUS Recovery恢复

华硕工厂文件恢复系统 &#xff0c;安装结束后带隐藏分区&#xff0c;一键恢复&#xff0c;以及机器所有驱动软件。 系统版本&#xff1a;windows10 原厂系统下载网址&#xff1a;http://www.bioxt.cn 需准备一个20G以上u盘进行恢复 请注意&#xff1a;仅支持以上型号专用…...

simulink绘制bode图

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…...

浏览器做单页网站项目/百度排名优化工具

安装 Linux 主机时,如果选择 最小化安装! 配置 vnc 远程桌面可以参考:Linux 配置 VNC 远程桌面 使用 vnc 等工具连接通常显示如下: 也就是无法使用图形化界面,可以通过 yum 直接安装图形化界面: Linux 6: yum groupinstall -y "X Window System" yum gr…...

网站关键词优化wang/seo引擎优化是做什么的

为什么80%的码农都做不了架构师&#xff1f;>>> 简单说说吧&#xff1a;我俩当年都是中兴15年那一批次的应届入职毕业生&#xff0c;一起参加入职公司级别的培训&#xff0c;一个班&#xff0c;一个小组。培训长达7天&#xff0c;无脑级别的洗脑&#xff08;你懂的…...

wordpress首页只能是page/关键词指数查询

别人文章参考&#xff1a;https://blog.csdn.net/kkevinyang/article/details/80539940 第三类错误&#xff1a;supervisord进程被占用的错误 查询进程&#xff0c;kill掉在重启 ps -ef | grep supervisord 报错信息&#xff1a; Exited too quickly (process log may have…...

深圳 营销型网站公司/青岛seo公司

第一周&#xff1a;做点计算1.1 第一个程序Eclipse是绝大多数人的唯一选择&#xff1b;如何在Eclipse中编辑、编译和运行程序&#xff1b;详解第一个程序&#xff1a;程序框架、输出、出错怎么办&#xff1b;做点计算&#xff1a;如何让程序输出算术结果1.2 数据是用变量来表示…...

重庆网站建设制作公司/日本积分榜最新排名

响应式编程在Android中的应用...

西安做网站程序/搜索引擎排名查询

Django模型Django 对各种数据库提供了很好的支持&#xff0c;包括&#xff1a;PostgreSQL、MySQL、SQLite、Oracle。 Django 为这些数据库提供了统一的调用API。 我们可以根据自己业务需求选择不同的数据库。 MySQL 是 Web 应用中最常用的数据库。本章节我们将以 Mysql 作为实例…...