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

C++类与对象 (上)

目录

前言:

类和对象的理解

类的引入

类的定义与使用方式

访问限定符

类的两种定义方式

成员变量的命名规则

类的作用域

类的实例化

类对象模型

计算类对象的大小

类对象的存储方式

this指针


前言:

  • C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题;
  • C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成;

类和对象的理解

是一个抽象的概念,描述了一类对象的共同属性行为

对象是类的具体化,它是类的实例,具有类中定义的属性和行为;

在C++中,通常由数据成员成员函数组成,数据成员是类的属性,它们描述了对象的状态,成员函数是类的行为,它们描述了对象可以执行的操作,对象的创建是通过类的实例化来完成的,当程序需要使用类时,可以通过创建类的对象来使用类的属性和行为;

举例如下:

将“汽车”看作一个类,在这个类中定义了汽车的属性和行为,比如颜色、品牌、速度等属性,以及加速、刹车、转弯等行为;当我们要描述具体一辆汽车时,就需要创建一个该类的对象,并根据需要设置其相应的属性值或对其进行行为操作;

类的引入

由于C++兼容C语言中struct的所有用法,同时C++对关键字struct进行了升级,将struct升级为类;

  •  struct    类名 (类名即为变量类型)
//c语言
struct Stack
{int* a;int top;int capacity;
};
int main()
{//Stack s1; //C语言 ---> 未定义的标识符struct Stack s1;//只能采取带上struct关键字定义变量return 0;
}
//c++ 
struct Stack
{int* a;int top;int capacity;
};
int main()
{Stack s1;//可直接采取这种方案定义变量,不需要加上struct的关键字return 0;
}
//c语言定义链表结点
struct ListNode
{//ListNode* next;//C语言 ---> 未定义的标识符struct ListNode* next;int val;
};
//c++定义链表结点
struct ListNode
{ListNode* next;//编译通过int val;
};
  • C++结构体中可以定义函数;
//c++ 类里面可以定义函数
struct Stack
{int* a;int top;int capacity;//初始化栈void Init(){a = 0;top = 0;capacity = 0;}
};

 C++用关键字 class 代替 struct;

类的定义与使用方式

class 类名
{//类体: 由成员变量与成员函数组成}; //此处分号不可省略

类的成员:类中的变量称为类的属性或成员变量类中的函数称为类的方法或成员函数

访问限定符

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

 访问限定符说明:

  1. public修饰的成员类外可以直接被访问
  2. protected和private修饰的成员类外不能直接被访问(此处protected和private是类似的)
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止;
  4. 如果后面没有访问限定符,作用域就到 } 即类结束;
  5. class的默认访问权限为privatestruct默认访问权限为public(因为struct要兼容C)
class Stack
{
private:int* a;int top;//a,top,capacity--->成员变量私有int capacity;//private的作用域从private开始到public,若没有public,直接到类结束;//由于class的默认访问权限为私有,省略掉private,三个成员变量依旧私有
public://初始化栈void Init()// Init()函数公有{a = 0;  top = 0;capacity = 0;}
}; //类结束

类定义的惯例:成员变量私有,成员函数公有;

class Stack
{
public:int* a;int top;int capacity;//初始化栈void Init(){a = 0;  top = -1;capacity = 0;}//空栈的判断bool StackEmpty(){return (top == -1);}
}; 
int main()
{Stack s1;s1.Init();//判断方式1:空栈, 若top=0,表示指向栈顶元素的下一个位置;//         空栈, 若top=-1,表示指向栈顶元素的位置;//栈的定义方式不同,如下判断方法可能导致出错;if (s1.top==0)//判断方式2:采取访问成员函数进行判断,直接调用判空函数,不会出错if (!s1.StackEmpty()){}//如上就是成员变量私有,成员函数公有的原因return 0;
}

类的两种定义方式

定义方式1:类的声明放在.h文件中,成员函数定义放在.cpp文件中;

                    (注:成员函数名前加 类名 ::)

定义方式2:声明和定义全部放在类体中;

                  (注:成员函数如果在类中定义编译器可能会将成员函数当成内联函数处理)

成员变量的命名规则

class Date
{
public:void Init(int year,int month,int day){// 这里的year到底是成员变量,还是函数形参?year = year;//局部优先,year为函数形参//局部优先是指在函数内部创建了一个和全局变量同名的局部变量时;//函数内部对该变量的操作会优先作用于局部变量,而不会改变全局变量的值}
private:int year;int month;int day;
};

为了避免如上情形,C++采用成员变量前加 _

class Date
{
public:void Init(int year,int month,int day){_year = year;}
private:int _year;int _month;int _day;//year month day成员变量前加 _
};

类的作用域

定义了一个 新的作用域类的所有成员都在类的作用域中
类体外定义成员时,需要使用 ::作用域限定符指明成员属于哪个 类域
c++中由{ }所定义的皆为作用域;
class Stack
{//变量的声明,没有在内存中开辟空间int* a;int top;int capacity;
public:void Init();bool StackEmpty();
};
//需要指定Init()函数属于Stack类域
void Stack::Init()
{a = 0;top = 0;capacity = 0;
}

类的实例化

用类的类型创建对象的过程,称为类的实例化;
  1. 类是对对象进行描述的是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;
  2. 一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量
class Date
{
public:void Init(int year,int month,int day){_year = year;}int _year;int _month;int _day;
};
int main()
{Date::_year = 2023;//编译错误,成员变量为声明,没有开辟内存空间存储;// Date d; d.year=2023  //正确做法return 0;
}
//Date类是没有空间的,只有Date类实例化出的对象才有具体的年份

3. 类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

类对象模型

类对象模型:类对象模型是指将类的成员函数和成员变量存储在一起的方式,这种方式将类的成员函数和成员变量封装在一个对象中,通过该对象来访问类的成员;

计算类对象的大小

# include <iostream>
using namespace std;
class Date
{
public:void Init(int year,int month,int day){_year = year;}int _year;int _month;int _day;
};
int main()
{Date d;cout << sizeof(d) << endl;return 0;
}
问题:类中既可以有成员变量,又可以有成员函数,那么一个类的对象中包含了什么?如何计算一个类的大小?

类对象的存储方式

类对象的存储方式:

对象中只保存成员变量,成员函数存放在公共代码段,这种方式将类的成员变量存储在对象中,而将成员函数存放在公共代码段中,通过对象来访问类的成员函数;

结论:一个类的对象大小,实际就是该类中”成员变量”之和,注意考虑内存对齐 ;

空类的大小:空类的大小为1字节;即使一个类没有任何成员变量和成员函数,它也会占用1字节的内存空间;

空的结构体大小:空的结构体大小为0字节,与空类不同,空的结构体不占用任何内存空间;

//类中仅有成员函数--->1byte
//对象中无成员函数
class B
{
public:void f2() {}
};
int main()
{B b;cout << sizeof(b) << endl;return 0;
}
//空类的大小 ---> 1byte
//无成员变量的类开辟1个字节,该字节不存储有效数据
//标识定义的对象存在过
class C
{};
int main()
{C c;cout << sizeof(c) << endl;return 0;
}

this指针

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;//日
};
int main()
{Date d1, d2;d1.Init(2023, 12, 17);d2.Init(2023, 12, 16);d1.Print();d2.Print();return 0;
}

运行结果:

Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,d1调用的Print()函数与d2调用的Print()函数相同,那当d1调用Print()函数时,该函数是如何知道应该显示d1对象,而不是显示d2对象呢?
C++ 中通过引入 this指针 解决该问题,即: C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量” 的操作,都是通过该指针去访问;只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成

this指针的特性:

  1. this指针的类型类型* const 由于const修饰this,this指针不允许被修改;
  2. 只能在“成员函数”的内部使用 (不能显示的写实参和形参,但是可以在类中显示的使用);
  3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参,所以对象中不存储this指针
  4.  this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递

相关文章:

C++类与对象 (上)

目录 前言&#xff1a; 类和对象的理解 类的引入 类的定义与使用方式 访问限定符 类的两种定义方式 成员变量的命名规则 类的作用域 类的实例化 类对象模型 计算类对象的大小 类对象的存储方式 this指针 前言&#xff1a; C语言是面向过程的&#xff0c;关注的是过…...

no module named ‘xxx‘

目录结构如下 我想在GCNmodel的model里引入layers的GraphConvolution&#xff1a;from GCNmodel.layers import GraphConvolution&#xff0c;但这样却报错no module named GCNmodel&#xff0c;而且用from layers import GraphConvolution也不行。然后用sys.path.appen(xxx)…...

Go实现MapReduce

背景 当谈到处理大规模数据集时&#xff0c;MapReduce是一种备受欢迎的编程模型。它最初由Google开发&#xff0c;用于并行处理大规模数据以提取有价值的信息。MapReduce模型将大规模数据集分解成小块&#xff0c;然后对这些小块进行映射和归约操作&#xff0c;最终产生有用的…...

Axure的交互样式和情形

Axure的交互样式和情形 交互样式 Axure是一个流行的原型设计工具&#xff0c;它允许您创建交互式原型&#xff0c;模拟应用程序或网站的功能和用户界面。在Axure中&#xff0c;您可以设置各种交互样式来使原型更加生动和真实。 链接触发器&#xff1a;通过给一个元素添加链接…...

Mybatis在新增某个数据后,如何获取新增数据的id

在某些业务中&#xff0c;我们在新增一条数据之后&#xff0c;需要拿到这条数据的id来对这条数据进行后续的一个操作&#xff0c;如何拿取id呢&#xff1f; 使用的是<insert> 中的useGeneratedKeys 和 keyProperty 两个属性 1.在Mybatis Mapper文件中添加属性 “useGene…...

12.4~12.14概率论复习与相应理解(学习、复习、备考概率论,这一篇就够了)

未分配的题目 概率计算&#xff08;一些转换公式与全概率公式&#xff09;与实际概率 &#xff0c;贝叶斯 一些转换公式 相关性质计算 常规&#xff0c;公式的COV与P 复习相关公式 计算出新表达式的均值&#xff0c;方差&#xff0c;再套正态分布的公式 COV的运算性质 如…...

关于多重背包的笔记

多重背包可以看作01背包的拓展&#xff0c; 01背包是选或者不选。多重背包是选0个一直到选s个。 for (int i 1; i < n; i) {for (int j m; j > w[i]; --j){f[j] max(f[j], f[j - 1*w[i]] 1*v[i], f[j - 2*w[i]] 2*v[i],...f[j - s*w[i]] s*v[i]);} } 由上述伪代码…...

如何使用 Java 的反射

如何使用 Java 的反射&#xff1f; 通过一个全限类名创建一个对象 Class.forName(“全限类名”); 例如&#xff1a;com.mysql.jdbc.Driver Driver 类已经被加载到 jvm 中&#xff0c;并且完成了类的初始化工作就行了 类名.class; 获取 Class<&#xff1f;> clz 对象对…...

PLC-Recorder V3 修改服务器和客户端通讯端口的方法

PLC-Recorder V3是服务器和客户端的架构&#xff0c;他们之间用TCP通讯。如果客户端无法与服务器建立连接&#xff08;重启也无效&#xff0c;并且确保没有老版本的PLC-Recorder在运行&#xff09;&#xff0c;则可能是端口被占用了。这时候需要修改他们之间的通讯端口&#xf…...

libevent服务GET/POST的简单使用

目录 1、前言2、测试demo2.1、目录结构2.2、 测试源码2.2.1、http_server.cpp2.2.2、 http_server.h 2.3、 编译2.4、 运行结果2.4.1、测试POST2.4.2 、测试GET请求 1、前言 项目开发中经常需要使用到私有协议和Qt,Android等GUI前端通信&#xff0c;比较常用的使用POST和GET方式…...

MySQL 系列:注意 ORDER 和 LIMIT 联合使用的陷阱

文章目录 前言背后的原因ORDER BY 排序列存在相同值时返回顺序是不固定的LIMIT 和 ORDER BY 联合使用时的行为ORDER BY 或 GROUP BY 和 LIMIT 联合使用优化器默认使用有序索引 如何解决其它说明个人简介 前言 不知道大家在在分页查询中有没有遇到过这个问题&#xff0c;分页查…...

通过实例理解OAuth2授权

在之前的《通过实例理解Go Web身份认证的几种方式[1]》和《通过实例理解Web应用授权的几种方式[2]》两篇文章中&#xff0c;我们对Web应用身份认证(AuthN)和授权(AuthZ)的几种方式做了介绍并配以实例增强理解。 在现实世界中&#xff0c;还有一大类的认证与授权是在前面的文章中…...

MATLAB2022安装下载教程

安装包需从夸克网盘自取&#xff1a; 链接&#xff1a;https://pan.quark.cn/s/373ffc9213a1 提取码&#xff1a;N7PW 1.将安装包解压 2.以管理员的身份运行文件夹中的setup文件 3.点击高级选项--->我有文件安装密钥 4. 选择【是】&#xff0c;进入下一步 5.输入密钥 0532…...

从零开始搭建Go语言开发环境

https://www.liwenzhou.com/posts/Go/install_go_dev/ “go 命令现在默认在模块感知模式下构建包&#xff0c;即使没有 go.mod 存在也是如此。 “您可以将 GO111MODULE 设置为 auto&#xff0c;仅当当前目录或任何父目录中存在 go.mod 文件时&#xff0c;才能启用模块感知模式…...

vite+vue3+ts+tsx+ant-design-vue项目框架搭建

参与公司项目开发一段时间了&#xff0c;项目用到了很多新的技术&#xff08;vite,vue3,ts等等&#xff09;&#xff0c;但是框架都是别人搭好的&#xff0c;然后就想说如果是自己的话&#xff0c;会从零搭建一个吗&#xff0c;于是就有了这篇文章。 目录 一、涉及到的相关依…...

【5G PHY】5G小区类型、小区组和小区节点的概念介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…...

创建个人网站(一)从零开始配置环境,搭建项目

目录 前言配置环境前端后端遇到的问题1.安装了nvm和node&#xff0c;vscode没反应2.安装完脚手架之后vue指令不存在 vscode插件&#xff08;以后遇到好的会添进去&#xff09; 前言 从刚开始学前端的html直到现在前后端都有在开发&#xff0c;我一直都有一个想法&#xff0c;就…...

fripside - promise lrc

[ti:promise] [ed:2] [rt:20] [ml:0|0] [00:05.172]words:Satoshi Yaginuma, Shinichiro Yamashita [00:09.664]music&arrangement:Satoshi Yaginuma, Shigetoshi Yamada [00:14.565]PCゲーム「ENGAGE LINKS」 (Alcot) エンディングテーマ [00:20.000] [00:46.442]朝の陽射…...

网络连接和协议

网络连接是通过一系列协议来实现的&#xff0c;其中TCP/IP协议和HTTP协议是其中两个关键的协议。 1. **TCP/IP协议&#xff1a;** - TCP/IP&#xff08;Transmission Control Protocol/Internet Protocol&#xff09;是一组用于在互联网上传输数据的协议。它是一个层次化的…...

MySQL数据库,表的增量备份与恢复

1. 从物理与逻辑的角度 数据库备份可以分为物理备份和逻辑备份。物理备份是对数据库操作系统的物理文件&#xff08;如数据 文件&#xff0c;日志文件等&#xff09;的备份。这种类型的备份适用于在出现问题时需要快速恢复的大型重要数据库。 物理备份又可以分为冷备份&#xf…...

汽车底盘松散?别忽视!成因与排查养护指南

对于每一位车主而言&#xff0c;汽车驾驶质感藏于细节&#xff0c;而底盘状态则是决定这份质感的核心。刚提新车时&#xff0c;驾驶紧致利落&#xff0c;过减速带悬挂反馈干脆&#xff0c;转弯车身平稳。然而&#xff0c;随着用车时间增长&#xff0c;底盘可能出现“松散感”&a…...

BilibiliDown音频提取技术指南:Java实现与配置深度解析

BilibiliDown音频提取技术指南&#xff1a;Java实现与配置深度解析 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_mirrors/…...

别再死记硬背PID参数了!手把手教你用AFM虚拟实验调出清晰形貌图

从零掌握AFM虚拟实验&#xff1a;PID调参实战指南与形貌优化技巧 第一次打开AFM虚拟实验界面时&#xff0c;面对密密麻麻的PID参数滑块&#xff0c;我完全懵了——P值调大还是调小&#xff1f;I参数到底影响什么&#xff1f;为什么别人的样品图像清晰锐利&#xff0c;而我的总是…...

2026年获客成本飙升?GEO优化让线索成本降低60%

2026年获客成本飙升&#xff1f;GEO优化让线索成本降低60% 摘要 &#xff1a;传统获客方式成本越来越高&#xff0c;百度竞价按点击付费&#xff0c;展会一次花费数万&#xff0c;线索成本难以下降。本文介绍一种新的获客方式——GEO优化&#xff0c;通过AI搜索优化直接触达目标…...

Buck电路纹波太大?可能是你的电容和ESR没选对!三种RC场景下的实战分析与选型指南

Buck电路纹波优化实战&#xff1a;电容与ESR选型的三维决策框架 实验室里示波器屏幕上那条本该平滑的直流输出波形&#xff0c;此刻却像心电图般剧烈起伏——这是每位电源工程师都经历过的"纹波焦虑"时刻。当我们面对Buck电路输出纹波超标问题时&#xff0c;传统定性…...

如何快速实现碧蓝航线全自动托管:智能脚本Alas终极指南

如何快速实现碧蓝航线全自动托管&#xff1a;智能脚本Alas终极指南 【免费下载链接】AzurLaneAutoScript Azur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研&#xff0c;全自动大世界 项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAutoScript 还在为碧…...

mimalloc内存分配器深度解析:高性能多线程环境下的内存管理优化方案

mimalloc内存分配器深度解析&#xff1a;高性能多线程环境下的内存管理优化方案 【免费下载链接】mimalloc mimalloc is a compact general purpose allocator with excellent performance. 项目地址: https://gitcode.com/GitHub_Trending/mi/mimalloc C/C开发者在构建…...

Faster RCNN PyTorch CUDA扩展:RoI Pooling层的GPU实现终极指南

Faster RCNN PyTorch CUDA扩展&#xff1a;RoI Pooling层的GPU实现终极指南 【免费下载链接】faster_rcnn_pytorch Faster RCNN with PyTorch 项目地址: https://gitcode.com/gh_mirrors/fa/faster_rcnn_pytorch 在目标检测领域&#xff0c;Faster RCNN一直是经典算法之…...

TegraRcmGUI终极指南:Windows上最简单的Switch注入工具

TegraRcmGUI终极指南&#xff1a;Windows上最简单的Switch注入工具 【免费下载链接】TegraRcmGUI C GUI for TegraRcmSmash (Fuse Gele exploit for Nintendo Switch) 项目地址: https://gitcode.com/gh_mirrors/te/TegraRcmGUI TegraRcmGUI是一款专为Nintendo Switch设…...

ShizuTools LookBack功能剖析:无需卸载即可降级应用的原理与实现

ShizuTools LookBack功能剖析&#xff1a;无需卸载即可降级应用的原理与实现 【免费下载链接】ShizuTools Contains many tools to control android system via shizuku. 项目地址: https://gitcode.com/gh_mirrors/sh/ShizuTools ShizuTools LookBack功能是一款创新的A…...