c++之类和对象上

目录

1. 类的定义

2. 访问限定符

3. 类域

4. 实例化

5. 对象的大小

6. 为什么要内存对齐

7. this指针


1. 类的定义

class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后⾯分号不能省
略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的⽅法或者成员函数。
为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前⾯或者后⾯加_ 或者 m 开头,注意C++中这个并不是强制的,只是⼀些惯例,具体看公司的要求。
C++中struct也可以定义类,C++兼容C中struct的⽤法,同时struct升级成了类,明显的变化是
struct中可以定义函数,⼀般情况下我们还是推荐⽤class定义类。
定义在类⾯的成员函数默认为inline。
class student
{//成员函数
public :void init(const char* name, int age, int score){_name = name;_age = age;_score = score;}void print(){cout<<"学生名字:" << _name<<endl<<"学生年龄:" << _age <<endl<<"学生得分:"<< _score << endl;}//成员变量
private:
// 为了区分成员变量,⼀般习惯上成员变量
// 会加⼀个特殊标识,如_ 或者 m开头const char *_name;int _age;int _score;
};
int main()
{student s1;s1.init("czy", 18, 100);s1.print();return 0;
}

c++升级了struct

// C++升级struct升级成了类
// 1、类⾥⾯可以定义函数
// 2、struct名称就可以代表类型
// C++兼容C中struct的⽤法
typedef struct ListNodeC
{
struct ListNodeC* next;
int val;
}LTNode;
// 不再需要typedef,ListNodeCPP就可以代表类型
struct ListNodeCPP
{
void Init(int x)
{
next = nullptr;
val = x;
}
ListNodeCPP* next;
int val;
};
//c语言中我们通常这样定义一个结点
typedef struct ListNodeC
{
struct ListNodeC* next;
int val;
}LTNode;
而在c++中我们可以直接如下定义struct ListNodeC
{ListNodeC* next;
int val;
};
//c++这种写法在c的源文件是过不去的
//但c的写法可以在cpp上通过
//也就是说我们不需要在typedef了后面跟的就是该结构体类型

2. 访问限定符

C++⼀种实现封装的⽅式,⽤类将对象的属性与⽅法结合在⼀块,让对象更加完善,通过访问权限
选择性的将其接⼝提供给外部的⽤⼾使⽤。
public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访
问,protected和private是⼀样的,以后继承章节才能体现出他们的区别。
访问权限作⽤域从该访问限定符出现的位置开始直到下⼀个访问限定符出现时为⽌,如果后⾯没有 访问限定符,作⽤域就到 }即类结束。
class定义成员没有被访问限定符修饰时默认为private,struct默认为public。
⼀般成员变量都会被限制为private/protected,需要给别⼈使⽤的成员函数会放为public,这样我们在类外部想要访问我们的成员变量,就要通过我们的成员函数进行操作。这里就体现出了c++的封装性,但是封装性的体现 :更多的是讲类的成员变量和成员函数放一起了,然后通过权限操作符给外部的用户使用这里就不细讲了。

3. 类域

类定义了⼀个新的作⽤域,类的所有成员都在类的作⽤域中,在类体外定义成员时,需要使⽤ :: 作
⽤域操作符指明成员属于哪个类域。
类域影响的是编译的查找规则,下⾯程序中Init如果不指定类域Stack,那么编译器就把Init当成全
局函数,那么编译时,找不到array等成员的声明/定义在哪⾥,就会报错。指定类域Stack,就是知
道Init是成员函数,当前域找不到的array等成员,就会到类域中去查找。
#include<iostream>
using namespace std;
class student{//成员函数public :void init(const char* name, int age, int score);void print();//成员变量private:const char *_name;int _age;int _score;};// 声明和定义分离,需要指定类域
void student::init(const char* name, int age, int score)
{{_name = name;_age = age;_score = score;}
}
void student::print()
{cout << "学生名字:" << _name << endl << "学生年龄:" << _age << endl<< "学生得分:" << _score << endl;
}
int main()
{student s1;s1.init("czy", 18, 100);s1.print();return 0;
}

4. 实例化

⽤类类型在物理内存中创建对象的过程,称为类实例化出对象。
类是对象进⾏⼀种抽象描述,是⼀个模型⼀样的东西,限定了类有哪些成员变量,这些成员变量只 是声明,没有分配空间,⽤类实例化出对象时,才会分配空间。
⼀个类可以实例化出多个对象,实例化出的对象 占⽤实际的物理空间,存储类成员变量。打个⽐
⽅:类实例化出对象就像现实中使⽤建筑设计图建造出房⼦,类就像是设计图,设计图规划了有多
少个房间,房间⼤⼩功能等,但是并没有实体的建筑存在,也不能住⼈,⽤设计图修建出房⼦,房
⼦才能住⼈。同样类就像设计图⼀样,不能存储数据,实例化出的对象分配物理内存存储数据。
#include<iostream>
using namespace std;
class student{//成员函数public :void init(const char* name, int age, int score);void print();//成员变量//这里没有实际的空间只是声明private:const char *_name;int _age;int _score;};// 声明和定义分离,需要指定类域
void student::init(const char* name, int age, int score)
{{_name = name;_age = age;_score = score;}
}
void student::print()
{cout << "学生名字:" << _name << endl << "学生年龄:" << _age << endl<< "学生得分:" << _score << endl;
}
int main()
{//类实例化后s1才有了空间student s1;s1.init("czy", 18, 100);s1.print();return 0;
}

5. 对象的大小

类对象通常是不存函数指针的,成员函数通常放在一个公共代码区,因此我们只要计算成员变量的大小就可以,这里我们补充一下内存对齐的知识:

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

6. 为什么要内存对齐

我们可以这样理解电脑可能是32位或者64位的这里我们假设是32位的也就是是说每次读取会获取32个比特位也就是四字节,每一个字节都有对应的编号,是从0开始的。下面我们看图

因为我们每次读取四字节如果有了内存对齐我们就可以一次读取到a,不内存对齐就会使我们读两次并且每次读的都是一部分还要合并删减等非常不方便。而内存对齐这样就解决了访问效率问题。

7. this指针

student类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当s1调⽤Init和
Print函数时,该函数是如何知道应该访问的是s1对象还是s2对象呢?那么这⾥就要看到C++给了
⼀个隐含的this指针解决这⾥的问题
编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this
指针。
类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_name赋值,_name = name;就相当于this->_name = name;
C++规定不能在实参和形参的位置显⽰的写this指针(编译时编译器会处理),但是可以在函数体内显
⽰使⽤this指针。
这里我们注意this指针不是在类对象中存放的,是在栈区有的编译器会把this放在在寄存器中,同时this指针可以为空,只要不通过this指针访问成员变量就不会报错,可以访问成员函数也不会报错,因为通过空的this去调用我们的成员函数时,并没有对this指向的空间进行操作。这里this指向的空间时当前类对象。也就是里面的成员变量。
这里我们就是取d1的地址放到了寄存器。

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

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

相关文章

(篇一)走进FreeRtos—认识FreeRtos

【温故知新篇】 【在现在的工作中一直在使用FreeRtos&#xff0c;但是对它的了解还是不够深入&#xff0c;现在由浅入深&#xff0c;分模块学习和记录&#xff0c;最后将自己基于FreeRtos开发项目实践】 首先我们将这个系统当作一座庄园&#xff0c;开始第一步走进庄园&#…

【备战秋招】——算法题目训练和总结day4

【备战秋招】——算法题目训练和总结day4&#x1f60e; 前言&#x1f64c;Fibonacci数列我的题解思路分享代码分享 单词搜索我的题解思路分享代码分享 杨辉三角我的题解思路分享代码分享 总结撒花&#x1f49e; &#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢…

ubuntu重装系统后,安装cuda,cudnn

一、 先安装驱动&#xff0c;如果驱动安装不成功&#xff0c;会影响桌面&#xff0c;再重装系统还来得及&#xff0c;尝试了很多方法&#xff0c;还是用系统安装最靠谱&#xff1a; 首先进入Ubuntu搜索栏目&#xff0c;找到软件更新器的一个图标&#xff0c;点开之后是这样的。…

开发个人Ollama-Chat--5 模型管理 (二)

开发个人Ollama-Chat–5 模型管理 (二) ChatGPT 这是该项目的最终效果&#xff0c;使用ollama的open-webui进行人与机器的对话功能&#xff0c;对话的后端服务则完全对接自己开发的Go项目。 如何实现呢&#xff1f;则通过这篇文章&#xff0c;一一给大家剖析后端的原理及功能…

mmaction2的GPU环境配置记录RTX3090,cuda12.2,ubuntu22.04版本

1、配置镜像源 最重要的一个步骤,先看下镜像源地址,如果镜像源有问题,所有的包安装都会有问题 镜像源地址获取地址:选择对应的ubuntu版本号,将里面的镜像源地址复制出来,更新到服务器 ubuntu | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirro…

牛客小白月赛98

骰子魔术 jackle 会拿出一枚骰子&#xff0c;骰子的表面分别写上了从 1∽5001\backsim 5001∽500 的数字&#xff0c;朋友会随便说一个 1∽5001\backsim 5001∽500 之间的点数&#xff0c;jackle 都能保证百分之百的掷出这个点数。 当然 jackle 有备而来&#xff0c;他准备了 …

LeetCode分发糖果(贪心思路分析)

题目描述 贪心思路 思路及解法 我们可以将「相邻的孩子中&#xff0c;评分高的孩子必须获得更多的糖果」这句话拆分为两个规则&#xff0c;分别处理。 左规则&#xff1a;当 ratings[i−1]<ratings[i] 时&#xff0c;i 号学生的糖果数量将比 i−1 号孩子的糖果数量多。 …

实现win10多用户同时远程连接登陆(详细实验步骤版)

目录 目的环境实验步骤&#xff08;在需要被远程的win10上&#xff09;1. 开启远程桌面服务2. 编辑组策略实现多用户登录3. 安装RDPWrap实现多用户同时登录 测试 目的 默认情况下&#xff0c;win10 专业版只支持本地或远程只能同时存在一个连接。windows server支持多连接。 比…

【unity笔记】十、Obi绳索插件使用

一. 创建绳索 1.1 新建蓝图 在Assets中右键选择创建->Obi->Rope Blueprint&#xff0c;其属性如图所示 1.2 Obi solver 在场景下创建一个obi solver对象&#xff0c;在该对象下再创建Obi Rope对象。 随后将蓝图拖到Obi Rope对象下的Obi Rope组件&#xff0c;即可看到…

MES系统与其他系统的集成:提升制造业智能化的关键路径

在当今高度竞争的制造业环境中&#xff0c;企业对于生产效率、质量控制、资源优化以及快速响应市场变化的需求日益迫切。制造执行系统&#xff08;MES&#xff09;作为连接企业计划层与车间控制层的重要桥梁&#xff0c;其在提升生产透明度和优化生产流程方面发挥着不可替代的作…

【SQL】如何用SQL写透视表

【背景】 报表中有一大需求是透视表,目前有很多分析类应用也搭载了此类功能,那么我们能不能直接用SQL做透视表呢? 【分析】 BI类软件将透视表功能做在了前端,但是数据本身还是存储在数据库中,所以必然有方法可以用SQL直接实现透视表。 【心法】 透视表是任意选取一个…

2024最新6月泛二级域名秒收泛目录(二级域名泛站群)

5月免费版本无后台 无更新功能不自动引蜘蛛 2024年5月最新泛程序&#xff0c;秒收秒排&#xff01;&#xff08;泛型程序&#xff09; - 虚良SEO博客 新曾功能&#xff1a; 后台管理 蜘蛛统计 域名添加 一键强引蜘蛛 蜘蛛统计 识别真假蜘蛛 全自动引蜘蛛 域名要求 …

Vue3-15 表单的绑定

在Vue 3中&#xff0c;表单输入绑定是实现动态数据双向绑定的重要部分&#xff0c;它让开发者可以轻松地管理和响应用户输入。本文将详细介绍如何在Vue 3中利用v-model指令以及一些特定修饰符来处理不同类型的表单输入。 响应式表单数据 首先&#xff0c;我们定义了一个响应式…

Linux /etc/profile 详解

概述 Linux是一个多用户的操作系统。每个用户登录系统后&#xff0c;都会有一个专用的运行环境。通常每个用户默认的环境都是相同的&#xff0c;这个默认环境实际上就是一组环境变量的定义。用户可以对自己的运行环境进行定制&#xff0c;其方法就是修改相应的系统环境变量&…

如何检测代理IP是否有效?检查因素与方法全解

代理IP是一种网络代理技术&#xff0c;它是通过中间服务器来转发网络请求的IP地址。当我们使用代理IP时&#xff0c;我们的真实IP地址会被隐藏起来&#xff0c;而代理服务器的IP地址会被用作我们的身份标识。使用代理IP的步骤如下&#xff1a; 1.选择合适的代理服务器 考虑服务…

【JavaEE】网络原理——传输层协议

&#x1f921;&#x1f921;&#x1f921;个人主页&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;JavaEE专栏&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;上一篇文章&#xff1a;【JavaEE】网络编程—…

CDGA|数据治理:标准化处理与确保数据可溯源性

在当今信息爆炸的时代&#xff0c;数据已成为企业决策、科学研究和政府管理的核心要素。然而&#xff0c;随着数据量的不断增加和来源的多样化&#xff0c;数据治理成为了一个亟待解决的问题。特别是在处理复杂数据时&#xff0c;标准化处理和确保数据的可溯源性显得尤为重要。…

ERROR: No matching distribution found for matplotlib

1.问题&#xff1a;安装matplotlib报错&#xff0c;如下图所示&#xff1a; 2.通过换源&#xff0c;输入以下命令&#xff1a;python -m pip install matplotlib -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com&#xff0c;但是还是无效 3.在pycharm中升级…

【java算法专场】滑动窗口(上)

目录 滑动窗口 基本概念 长度最小的子数组 算法分析 算法步骤 示例 算法代码 无重复字符的最长子串 算法分析 算法步骤 示例 算法代码 最大连续1的个数 III 算法分析 算法步骤 示例 算法代码 将 x 减到 0 的最小操作数 算法分析 算法步骤 示例 算法代码 滑动…

location匹配的优先级和重定向

nginx的重定向&#xff08;rewrite&#xff09; location 匹配 location匹配的就是后面的uri /wordpress 192.168.233.10/wordpress location匹配的分类和优先级 1.精确匹配 location / 对字符串进行完全匹配&#xff0c;必须完全符合 2.正则匹配 ^-前缀级别&#xff…