【C++】类和对象--类,实例化,this指针

文章目录

  • 前言
  • 一、类
    • 1.1 类的定义
    • 1.2 类的书写和使用
    • 1.3 访问限定符
    • 1.4 类域
  • 二、实例化
    • 2.1 实例化概念
    • 2.2 对象大小
  • 三.this指针
  • 总结


在这里插入图片描述

前言

前面的几篇文章我们介绍了命名空间,inline,nullptr等C++
中常见的的基础概念。今天的文章我们来介绍一些C++中类与对象的内容。


一、类

1.1 类的定义

在现实世界中,经常有属于同一类的对象。例如,你的自行车只是世界上很多自行车中的一辆。在面向对象软件中,也有很多共享相同特征的不同的对象:矩形、雇用记录、视频剪辑等。可以利用这些对象的相同特征为它们建立一个集合。而这个集合就称为类。类是定义同一类所有对象的变量和方法的蓝图或原型。

1.2 类的书写和使用

class Stack
{
public:void Init(int n=4){int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc");return;}a = tmp;size = top = 0;}void Push(int x){if (top == size){int newsize = size * 2;int* tmp = (int*)realloc(a, sizeof(int) * newsize);if (tmp == NULL){perror("realloc");return;}a = tmp;}a[top] = x;top++;}
private:int* a;int top;int size;
};

class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数。

class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year; // year_ m_yearint _month;int _day;
};

在定义类的成员名称时,为了与函数的形参区分,一般会在变量名前面加上"_"或者m,这个在C++标准中并没有明确规定,根据实际需求使用。

struct ListNodeCPP
{void Init(int x){next = nullptr;val = x;}ListNodeCPP* next;int val;
};

C++中的结构体也可以定义类,C++中兼容C的结构体并将其升级为类。在结构体内部也可以定义函数。并且在C++中结构体的名字直接可以作为类型名,这就省去了我们通过typedef简化掉struct的过程。但是我们还是推荐使用class来定义类。

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

1.3 访问限定符

在上面的Stack类中,我们发现有public和private这两个单词。这就是访问限定符。访问限定符有三个
在这里插入图片描述
• 这是C++⼀种实现封装的方式,用类将对象的属性与方法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。

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

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

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

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

•在一个类中可以有多个public,private等限制符,但是方便起见,我们一般把他们放在一起。

1.4 类域

  • 类定义了⼀个新的作用域,类的所有成员都在类的作用域中,在类体外定义成员时,需要使用::作用域操作符指明成员属于哪个类域。
  • 类域影响的是编译的查找规则,下面程序中Init如果不指定类域Stack,那么编译器就把Init当成全局函数,那么编译时,找不到数组a等成员的声明/定义在哪里,就会报错。指定类域Stack,就是知道Init是成员函数,当前域找不到的a等成员,就会到类域中去查找。
class Stack
{
public:void Init(int n = 4);
private:int* a;size_t capacity;size_t top;
};
// 声明和定义分离,需要指定类域
void Stack::Init(int n)
{a = (int*)malloc(sizeof(int) * n);if (nullptr == a){perror("malloc申请空间失败");return;}capacity = n;top = 0;
}

二、实例化

2.1 实例化概念

⽤类类型在物理内存中创建对象的过程,称为类实例化出对象。我们创建出一个类,相当于画出了一个图纸,我们通过这个图纸建造出的房屋就是实例。所以实例化就是从图纸到房屋的过程。我们只定义出一个类,它是不用空间,只有将它实例化后才会开辟空间。
在这里插入图片描述

2.2 对象大小

首先我们先来分析一下类对象中有哪些成员?成员函数+成员变量。类实例化后的每个对象都有独立的数据空间,所以成员变量是要占据一定空间的。那么成员函数是否占用空间呢?首先函数被编译后是一段指令,对象中无法存储,这些指令存储在一个单独的区域(代码段),如果对象中想要存储他,就只能存储成员函数的指针。我们在分析一下,每一个实例的成员变量都有自己的空间是因为,每一个实例的变量可能不同所以单独存储,但是每一个实例中的成员函数的指针是一样的,如果每实例化一个对象都开辟空间就会产生浪费。所以成员函数是不储存在对象内的。其实函数指针不需要存储,函数指针是一个地址,调用函数被编译成汇编指
令[call地址],其实编译器在编译链接时,就要找到函数的地址,不是在运行时找,只有动态多态是在运行时找,就需要存储函数地址。

上面我们分析了对象中只存储成员变量,C++规定类实例化的对象也要符合内存对齐的规则。

内存对齐规则
• 第⼀个成员在与结构体偏移量为0的地址处。
• 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
• 注意:对齐数=编译器默认的⼀个对齐数与该成员大小的较小值。
• VS中默认的对齐数为8
• 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
• 如果嵌套了结构体的情况,嵌套的结构体对齐到在自己的最大对齐数的整数倍处,结构体的整体大小
就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

我们再来看一段代码,思考它的结果是什么

class A
{
public:void Print(){//...}
};
class B
{};
int main()
{A b;B c;cout << sizeof(b) << endl;cout << sizeof(c) << endl;return 0;
}

在这里插入图片描述
上面的程序运行后,我们看到没有成员变量的B和C类对象的大小是1,为什么没有成员变量还要给1个字节呢?因为如果⼀个字节都不给,怎么表示对象存在过呢?所以这里给1字节,纯粹是为了占位标识对象存在。

三.this指针

this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。

例如,调用date.SetMonth(9) <===> SetMonth(&date, 9),this帮助完成了这一转换 .

class Date
{
public:// void Init(Date* const this, int year, int month, int day)void Init(int year, int month, int day){// this->_year = year;_year = year;this->_month = month;this->_day = day;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};

this指针是类的一个自动生成、自动隐藏的私有成员,它存在于类的非静态成员函数中,指向被调用函数所在的对象。全局仅有一个this指针,当一个对象被创建时,this指针就存放指向对象数据的首地址。

关于this指针的一个经典回答:
当你进入一个房子后,
你可以看见桌子、椅子、地板等,
但是房子你是看不到全貌了。
对于一个类的实例来说,
你可以看到它的成员函数、成员变量,
但是实例本身呢?
this是一个指针,它时时刻刻指向你这个实例本身


总结

以上就是今天的全部内容,主要介绍了一些C++的基础内容,C++的内容还有许多,如果喜欢这篇博客,期待你的一键三连。

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

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

相关文章

数据结构 —— BellmanFord算法

数据结构 —— BellmanFord算法 BellmanFord算法检测负权值环BellmanFord和Dijkstra思想上的区别Dijkstra算法的思想Bellman-Ford算法的思想思想上的对比 我们今天来看一个算法BellmanFord算法&#xff0c;我们之前的Dijkstra算法只能用来解决正权图的单源最短路径问题。 Bell…

C语言入门基础题:奇偶 ASCII 值判断(C语言版)和ASCII码表,什么是ASCII码,它的特点和应用?

1.题目描述&#xff1a; 任意输入一个字符&#xff0c;判断其 ASCII 是否是奇数&#xff0c;若是&#xff0c;输出 YES &#xff0c;否则&#xff0c;输出 NO例如&#xff0c;字符 A 的 ASCI 值是 65 &#xff0c;则输出 YES &#xff0c;若输入字符 B(ASCII 值是 66)&#xff…

数据库的学习(5)

题目&#xff1a; 1、新增员工表emp和部门表dept create table dept (deptl int,dept name varchar(11)) charsetutf8; create table emp (sid int,name varchar(11),age int,worktime start date,incoming int,dept2 int) charsetutf8; insert into dept values (101,财务), (…

Matlab中如何添加OptiluX?

1、打开Matlab&#xff0c;依次点击“新建”&#xff0c;“工程”&#xff0c;“从SVN”。 2、存储库路径输入&#xff1a; p/optilux/code - Revision 80: /trunk 同时在“源代码控制集成”菜单中选择“SVN (1.9)” 3、沙盒选择一个自己建的文件夹即可。 来源&#xff1a;Opt…

特征值究竟体现了矩阵的什么特征?

特征值究竟体现了矩阵的什么特征&#xff1f; 简单来说就是x经过矩阵A映射后和自己平行 希尔伯特第一次提出eigenvalue,这里的eigen就是自己的。所以eigenvalue也称作本征值 特征值和特征向量刻画了矩阵变换空间的特征 对平面上的任意向量可以如法炮制&#xff0c;把他在特征…

集创北方ICN6202 低功耗MIPIDSI转2 PORT LVDS 支持1080P分辨率,成熟批量产品

ICN6202描述&#xff1a; ICN6202是一个接收MIPIDSI输入和发送LVDS输出的桥接芯片。MIPIDSI最多支持4个车道&#xff0c;每个车道的最大运行频率为1Gbps&#xff1b;总最大输入带宽为4Gbps&#xff1b;并且还支持MIPI定义的ULPS&#xff08;超低功耗状态&#xff09;。ICN6202…

Elasticsearch集群搭建

集群概念 在单台 ES 服务器上&#xff0c;随着一个索引内数据的增多&#xff0c;会产生存储、效 率、安全等问题。 因此引入集群 我们需要将索引拆分成多份&#xff0c;分别放入不同的服务器中&#xff0c;此时这几台服务器维护了同一个索引&#xff0c;我们称这几台服务器为一…

计算机毕业设计Python深度学习游戏推荐系统 Django PySpark游戏可视化 游戏数据分析 游戏爬虫 Scrapy 机器学习 人工智能 大数据毕设

本论文的主要研究内容如下&#xff1a; 了解基于Spark的TapTap游戏数据分析系统的基本架构&#xff0c;掌握系统的开发方法&#xff0c;包括系统开发基本流程、开发环境的搭建、测试与运行等。 主要功能如下&#xff1a; &#xff08;1&#xff09;用户管理模块&#xff1a…

初阶数据结构—排序

第一章&#xff1a;排序的概念及其运用 1.1 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有…

LIO-SAM编译ubuntu20.04 Noetic

一、下载 mkdir -p ~/lio_sam_ws/src cd ~/lio_sam_ws/src git clone https://github.com/TixiaoShan/LIO-SAM.git cd ..二、编译&&解决报错 catkin_make报错如下 解决方案&#xff1a; 第一步&#xff1a; sudo add-apt-repository ppa:borglab/gtsam-release-4…

数学建模美赛经验小结

图片资料来自网络所听讲座&#xff0c;感谢分享&#xff01;

网络编程的学习之udp

Udp编程过程 Sento不会阻塞 实现聊天室效果 上线 聊天 下线 服务端需要一个地址&#xff0c;去保留名字和ip地址 交互的时候发结构体 下面这个宏只能在c语言里使用 ser.sin_port htons(50000); 上面是端口号50000以上&#xff0c;两边要一样 这里是不要让udp发的太快&am…

Unity Shader学习笔记

Shader类型 类型详情Standard Surface Shader标准表面着色器&#xff0c;基于物理的着色系统&#xff0c;用于模拟各种材质效果&#xff0c;如石头、木材、玻璃、塑料和金属等。Unlit Shader最简单的着色器&#xff0c;不包含光照但包含雾效&#xff0c;只由最基础的Vertex Sh…

30. 梯度下降法及其应用

1. 引言 在深度学习中&#xff0c;损失函数的求解是一个关键步骤。损失函数通常没有解析解&#xff0c;因此需要通过最优化算法来逼近求解。其中&#xff0c;梯度下降法是最常用的优化算法之一。本文将详细介绍梯度下降法的基本概念、理论基础、及其在深度学习中的应用。 2. …

甄选范文“论基于构件的软件开发方法及其应用”,软考高级论文,系统架构设计师论文

论文真题 基于构作的软件开发 (Component-Based Software Development,CBSD) 是一种基于分布对象技术、强调通过可复用构件设计与构造软件系统的软件复用途径。基于构件的软件系统中的构件可以是COTS (Commercial-Off-the-Shelf)构件,也可以是通过其它途径获得的构件(如自…

2970.力扣每日一题7/10 Java(暴力枚举)

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;算法练习关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 目录 解题思路 解题方法 时间复杂度 空间复杂度 Code 解题思路 incre…

图论---无向图中国邮路的实现

开始编程前分析设计思路和程序的整体的框架&#xff0c;以及作为数学问题的性质&#xff1a; 程序流程图&#xff1a; 数学原理&#xff1a; 本质上是找到一条欧拉回路&#xff0c;考虑图中的边权重、顶点的度数以及如何通过添加最少的额外边来构造欧拉回路&#xff0c;涉及到欧…

链表 OJ(一)

移除链表元素 题目连接&#xff1a; https://leetcode.cn/problems/remove-linked-list-elements/description/ 使用双指针法&#xff0c;开始时&#xff0c;一个指针指向头节点&#xff0c;另一个指针指向头节点的下一个结点&#xff0c;然后开始遍历链表删除结点。 这里要注…

推荐一款功能强大的 GPT 学术优化开源项目GPT Academic:学术研究的智能助手

今天&#xff0c;我将向大家介绍一个强大的开源项目—GPT Academic&#xff0c;它或许正是你一直在寻找的理想工具。 已一跃成为 60.4k Star 的热门项目 GPT Academic 目前在 GitHub 上已经揽获了 60.4k 的 Star&#xff0c;这不仅反映了它的受欢迎程度&#xff0c;更证明了它…

硅纪元AI应用推荐 | 百度橙篇成新宠,能写万字长文

“硅纪元AI应用推荐”栏目&#xff0c;为您精选最新、最实用的人工智能应用&#xff0c;无论您是AI发烧友还是新手&#xff0c;都能在这里找到提升生活和工作的利器。与我们一起探索AI的无限可能&#xff0c;开启智慧新时代&#xff01; 百度橙篇&#xff0c;作为百度公司在202…