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

【C++入门】浅谈类、对象和 this 指针

文章目录

  • 一、前言
  • 二、类
    • 1. 基本概念
    • 2. 类的封装
    • 3. 使用习惯
      • 成员函数定义习惯
      • 成员变量命名习惯
  • 三、对象
    • 1. 基本概念
    • 2. 类对象的存储规则
  • 四、this 指针
    • 1. 基本概念
    • 2. 注意事项
    • 3. 经典习题
    • 4. 常见面试题

一、前言

在 C 语言中,我们用结构体来描述一个事物的多种属性。

struct person
{int age;char name[10];
};

而 C++ 则引入了类,相比结构体内只能定义变量,类还可以定义函数。
下面声明一个类,类名为person

//class关键字
class person
{void init(...){...}int age;char name[10];
};

上面代码只是类的声明,没有占用实际的空间。
用类创建对象,称作类的实例化。
实例化的对象才会占用实际的物理空间。

创建对象:类名 + 对象名
例子:

person a;

上述代码创建了一个person类的对象a,对象才占有实际空间。

而 C 语言中的struct关键字,在 C++ 中也升级成了类,不过 C++ 中的struct关键字依然兼容 C语言的结构体写法。

//C++ 中的类
struct person
{void init(...){...}int age;char name[10];
};
//创建一个person类的对象b
person b;//C 语言中的结构体
struct person
{int age;char name[10];
};
//创建一个结构体变量c
struct person c;
//也可以这样写,此时person被看作一个类
person c;

二、类

1. 基本概念

类中的内容称为成员。
类中的变量称为属性或成员变量,类中的函数称为方法或成员函数。

2. 类的封装

C++ 中的类是用于实现封装的,封装是面向对象的三大特性之一,简单来说,封装就是将对象的属性和方法有机结合,隐藏内部实现细节,仅对外提供接口用于交互。就像电脑主机内部封装了各种硬件的实现细节,仅提供开机按钮、鼠标和键盘等让用户和计算机交互。
如何隐藏内部实现细节呢,C++ 提供了三个访问限定符,publicprivateprotected
public修饰的成员可以在类外访问,privateprotected修饰的成员不能在类外访问。
class的默认访问权限为privatestructpublic

3. 使用习惯

成员函数定义习惯

第一种是成员函数的声明和定义都在类中。

class person
{
public:void print(){...}
private:int age;char name[10];
};

需要注意的是,这种方式的成员函数定义在类中,编译器可能会将其当作内联函数处理。

另一种则是成员函数的声明在类中(类在头文件声明),定义体在类外(cpp文件)。一般建议使用这种方式。

//person.h
class person
{
public:void print();private:int age;char name[10];
};//person.cpp
void person::print()//注意要加 person::
{...
}

一个类就是一个新的作用域(事实上,C++ 中一对大括号就是一个域),类的所有成员都在类的域中,因此在类外定义类的成员函数时,函数名前要加类名::

成员变量命名习惯

一般会给变量名加个前缀或后缀,用于区分成员变量和成员函数形参。

例子:

class person
{
public:void init(int age, char name[]){...}
private:int _age;       //或 mAgechar _name[10]; //或 mName
};

三、对象

1. 基本概念

简单来说,类是对一类事物的抽象描述,只是一个声明,不占物理空间。而类的对象就是类的一个实例化,是真实存在在内存空间的。

2. 类对象的存储规则

一个类对象在内存中只会存储它的成员变量,成员函数则是放在公共代码区,供类的所有对象使用。

那么如何计算sizeof类对象的大小呢?
事实上,类对象的大小等价于类的大小,因为sizeof是根据类型确定大小的。
而类对象中只存储它的成员变量,因此只需计算类的所有成员变量所占空间的大小即可。
与 C 语言中计算结构体的大小相同,计算类的大小也要考虑内存对齐的规则,具体可以参考这篇文章:传送门

另外,空类比较特殊(包括没有成员变量的类,因为成员函数是存在公共代码区的,不参与类大小的计算),空类的大小不是 0,编译器会给空类 1 个字节来唯一标识这个类的对象,因此空类的大小是 1 。

四、this 指针

1. 基本概念

在对象调用成员函数的时候,编译器会自动给函数传递对象的地址,当作被调函数的一个指针形参,这个指针就叫做this指针。该指针用于在成员函数中访问对象的成员变量。(由上文可知,对象只会存储自己的成员变量,成员函数时放在公共代码区的)

在这里插入图片描述

事实上,编译器给每个非静态的成员函数都隐藏了一个this指针参数。相比于 C 语言,调用成员函数时,我们不用自己传递对象的地址,编译器会帮我们完成。

2. 注意事项

this指针本质是一个常量指针,不能修改指向。

由于this指针是对象调用成员函数时,成员函数隐藏的一个指针形参,所以this指针的作用域是成员函数内部。

对象调用成员函数时,对象的地址作为实参传递给this形参。而作为一个形参,this指针应当存在函数栈帧中,有的编译器为了提高效率也会把this指针存在寄存器。

3. 经典习题

//1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:void Print(){cout << "Print()" << endl;}
private:int _a;
};int main()
{A* p = nullptr;p->Print();return 0;
}

本题结果为正常运行。

在本题中,对象地址为空,所以对象调用成员函数的时候,传给成员函数this形参的是空指针。由于成员函数是存在公共代码区的,而不是存在对象中,所以对象地址为空并不影响调用成员函数。本题的成员函数内部,并没有对this形参的解引用,因此不存在对空指针解引用的问题,所以程序正常运行。

tips:程序里有空指针,编译是不会报错的,最多就是警告。所以我们写代码如果不小心对空指针解引用,编译是不会报错的,但是运行程序的时候就会崩溃。

//2.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:void PrintA(){cout << _a << endl;}
private:int _a;
};int main()
{A* p = nullptr;p->PrintA();return 0;
}

本题结果为运行崩溃。

本题与上题的唯一区别在于,本题的成员函数内部访问了对象的成员变量,因此存在对this指针的解引用。而对象的地址为空,所以传给成员函数的this形参是空指针,因此出现了对空指针解引用的行为,程序运行崩溃。

4. 常见面试题

综上,我们就能回答两个常见的面试题。

this指针存在哪里:
this指针作为成员函数隐藏的形参,存在函数栈帧中,也有可能存在寄存器。

this指针可以为空吗:
可以,但是成员函数内不能访问对象的成员变量,即不能对this指针解引用。

相关文章:

【C++入门】浅谈类、对象和 this 指针

文章目录 一、前言二、类1. 基本概念2. 类的封装3. 使用习惯成员函数定义习惯成员变量命名习惯 三、对象1. 基本概念2. 类对象的存储规则 四、this 指针1. 基本概念2. 注意事项3. 经典习题4. 常见面试题 一、前言 在 C 语言中&#xff0c;我们用结构体来描述一个事物的多种属性…...

【Linux命令200例】indent对C语言代码进行缩进和格式化

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;本文已收录于专栏&#xff1a;Linux命令大全。 &#x1f3c6;本专栏我们会通过具体的系统的命令讲解加上鲜活的实操案例对各个命令进行深入…...

Hive 调优集锦(1)

一、前言 1.1 概念 Hive 依赖于 HDFS 存储数据&#xff0c;Hive 将 HQL 转换成 MapReduce 执行&#xff0c;所以说 Hive 是基于Hadoop 的一个数据仓库工具&#xff0c;实质就是一款基于 HDFS 的 MapReduce 计算框架&#xff0c;对存储在HDFS 中的数据进行分析和管理。 1.2 架…...

【C++详解】——智能指针

目录 为什么需要智能指针 抛异常引发内存泄漏 内存泄漏 什么是内存泄漏&#xff0c;内存泄漏的危害 内存泄漏分类 检测内存泄漏常用工具 如何避免内存泄漏 智能指针的使用及原理 RAII 智能指针的原理 各类智能指针介绍 auto_ptr unique_ptr shared_ptr weak_ptr …...

Jmeter接口/性能测试,Jmeter使用教程(超细整理)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、线程组 线程组…...

59,综合案例-演讲比赛流程管理系统

演讲比赛流程管理系统 59.1案例描述59.1.1比赛规则59.1.2程序功能 59.2创建管理类59.3菜单功能59.3.1添加成员函数59.3.2菜单功能实现 59.4退出功能59.4.1提供功能接口59.4.2实现退出功能 59.5演讲比赛功能59.5.1创建选手类59.5.2比赛59.5.2.1成员属性添加59.5.2.2初始化属性59…...

前端JS 展示上传图片缩略图(本地图片读取)

需求&#xff1a; 点击上传图片按钮&#xff0c;选择图片以后&#xff0c;不请求后端接口&#xff0c;直接将图片展示在缩略图中。 解决方案&#xff1a; 使用 FileReader 和 FileReader 中的 readAsDataURL 方法。 第一步 从input[type“file”] (上传文件标签) 里面拿到fil…...

Vue中$route和$router的区别

$router&#xff1a;用来操作路由&#xff0c;$route&#xff1a;用来获取路由信息 $router其实就是VueRouer的实例&#xff0c;对象包括了vue-router使用的实例方法&#xff0c;还有实例属性&#xff0c;我们可以理解为$router有一个设置的含义&#xff0c;比如设置当前的跳转…...

基于多任务学习卷积神经网络的皮肤损伤联合分割与分类

文章目录 Joint segmentation and classification of skin lesions via a multi-task learning convolutional neural network摘要本文方法实验结果 Joint segmentation and classification of skin lesions via a multi-task learning convolutional neural network 摘要 在…...

串口环形缓冲区

文章目录 一、串口环形缓冲区概念二、STC12例程&#xff08;1&#xff09;环形串口缓冲区结构体&#xff08;2&#xff09;串口环形缓冲区存和取数据&#xff08;3&#xff09;完整工程demo 一、串口环形缓冲区概念 串口环形缓冲区应用于嵌入式、物联网开发中处理接收串口数据…...

【腾讯云 Cloud Studio 实战训练营】基于Cloud Studio完成简易通讯录

目录 &#x1f506;Cloud Studio 简介 操作步骤 1.登录 2.创建工作空间 3.初始界面 4.开发空间 5.保存自定义模板 &#x1f506;简易通讯录 1.实验要求 2.操作环境 3.源代码介绍 3.1 定义通讯录类 3.2 定义通讯录列表 3.3 添加联系人功能 3.4 修改联系人 3.5 …...

【技术积累】Vue.js中的核心知识

Vue的生命周期 Vue中的生命周期是指组件从创建到销毁的整个过程中&#xff0c;会触发一系列的钩子函数 Vue2中的生命周期 Vue2中的生命周期钩子函数是在组件的不同阶段执行的特定函数。这些钩子函数允许开发者在组件的不同生命周期阶段执行自定义的逻辑。 Vue2中的生命周期钩…...

flutter开发实战-显示本地图片网络图片及缓存目录图片

flutter开发实战-显示本地图片网络图片及缓存目录图片 在最近开发中碰到了需要显示缓存目录图片&#xff0c;这里顺便整理一下&#xff0c;显示本地图片、网络图片、缓存目录图片的方法。 一、工程本地图片显示 1 在项目根目录下创建名为 images文件夹&#xff0c;也可以将i…...

面对未来的算法备案法规:企业需要做哪些准备?

在信息时代&#xff0c;算法已经成为我们生活的一部分&#xff0c;涵盖了诸如搜索引擎、社交媒体、电子商务、广告投放等各个方面。然而&#xff0c;随着算法的广泛应用&#xff0c;其带来的问题也日益凸显。这引发了全球范围内的关注&#xff0c;未来的算法备案法规正在酝酿之…...

iptables的备份和还原

iptables的备份和还原 1、写在命令行当中的都是临时设置 2、把规则配置写在服务的文件当中&#xff0c;形成永久有效 备份&#xff1a;把iptables里面所有的配置都保存在/opt/ky30.bak中 iptables-save > /opt/ky30.bak 例&#xff1a; 默认配置文件在/etc/sysconfig/ip…...

easyUI框架学习

文章目录 一、前言二、引入使用easyUI 三、用法3.1 Dialog&#xff08;对话框窗口&#xff09;3.1.1 示例13.1.2 示例2 3.2 Layout&#xff08;布局&#xff09;3.2.1 示例1——通过标签创建布局3.2.2 示例2—— 创建嵌套布局 3.3 DateBox&#xff08;日期输入框&#xff09;3.…...

加入气压计模组,星斗3号将实现快速三维定位

随着信息技术的飞速发展,人们的生活正在发生巨大改变,人们对基于位置服务的需求越来越迫切,尤其是室内位置服务。 室外定位系统中BDS系统、GPS系统等受室内复杂环境条件限制精度大幅下降甚至失效,难以在室内定位中发挥作用,而室内二维定位技术缺乏高程信息,也难以满足人们对室…...

华为HCIP第二节-------------------------ISIS

IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是ISO &#xff08;International Organization for Standardization&#xff0c;国际标准化组织&#xff09;为它的CLNP&#xff08;ConnectionLessNetwork Protocol&…...

在Mac系统下搭建Selenium环境并驱动Chrome浏览器

本文带领那些使用Mac的童鞋们实现Selenium驱动Chrome浏览器&#xff0c;虽然会有坑&#xff0c;但是我们可以凭借敏捷的身手躲过。下面就开始吧&#xff1a; 安装selenium 打开终端 ->pip安装&#xff08;安装命令&#xff1a;pip3 install selenium&#xff09; 安装浏览…...

通过RPM方式安装,升级,卸载,以及配置使用MySQL

通过RPM方式安装&#xff0c;升级&#xff0c;卸载&#xff0c;以及配置使用MySQL 一、下载 MySQL是一种开源的关系数据库管理系统&#xff0c;被广泛应用于各种业务应用中。本文将讲解如何下载和安装MySQL的rpm安装包。 下载rmp安装包有多种方式&#xff1a; 1、官网下载 …...

想实现SpringCloud的负载均衡,需要实现哪些接口和规范

前几天有个大兄弟问了我一个问题&#xff0c;注册中心要集成SpringCloud&#xff0c;想实现SpringCloud的负载均衡&#xff0c;需要实现哪些接口和规范。既然这个兄弟问到我了&#xff0c;而我又刚好知道&#xff0c;这不得好好写一篇文章来回答这个问题&#xff0c;虽然在后面…...

腾讯地图SDK隐私协议合规接入实战:你的App真的合法显示地图了吗?

腾讯地图SDK隐私合规实战&#xff1a;从法律条文到代码落地的全流程指南 当你的App因为地图功能被应用商店拒审时&#xff0c;当用户投诉你的应用"偷偷收集位置信息"时&#xff0c;当合规团队发来长达20页的整改清单时——这些场景正在成为移动开发者的日常。去年某社…...

探索Godot Open RPG:5步打造零基础可玩的回合制RPG游戏

探索Godot Open RPG&#xff1a;5步打造零基础可玩的回合制RPG游戏 【免费下载链接】godot-open-rpg Learn to create turn-based combat with this Open Source RPG demo ⚔ 项目地址: https://gitcode.com/gh_mirrors/go/godot-open-rpg 想开发属于自己的角色扮演游戏…...

嵌入式WiFi开发 | 基于wireless_tools的交叉编译实战与移植指南

1. 嵌入式WiFi开发入门&#xff1a;为什么需要wireless_tools&#xff1f; 在嵌入式Linux开发中&#xff0c;网络连接能力往往是刚需。想象一下你的智能家居设备需要自动连接路由器&#xff0c;或者工业传感器需要通过WiFi上传数据——这些都离不开可靠的无线网络配置工具。这就…...

别再让输入框‘抢焦点’了!手把手封装一个Vue扫码枪工具类SCAN,解决页面刷新监听丢失

从零构建高可靠Vue扫码枪工具库&#xff1a;SCAN类深度封装与工程化实践 扫码枪在零售、仓储、医疗等行业的Web系统中应用广泛&#xff0c;但传统实现强依赖输入框焦点&#xff0c;用户体验差且稳定性低。本文将带你从底层原理出发&#xff0c;完整封装一个无需输入框聚焦、支持…...

从SUB、PUSH到栈操作:5条指令带你吃透微程序控制器设计核心

从SUB、PUSH到栈操作&#xff1a;5条指令带你吃透微程序控制器设计核心 在计算机组成原理的探索中&#xff0c;微程序控制器设计一直是连接硬件与软件的桥梁。不同于直接通过硬连线控制&#xff0c;微程序控制采用"存储逻辑"的思想&#xff0c;将每条机器指令的执行分…...

如何参与Data-Science-For-Beginners社区贡献:完整开源项目参与指南

如何参与Data-Science-For-Beginners社区贡献&#xff1a;完整开源项目参与指南 【免费下载链接】Data-Science-For-Beginners 10 Weeks, 20 Lessons, Data Science for All! 项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners Data-Scienc…...

告别Keil:用VS Code + EIDE打造高效C51开发环境

1. 为什么我们要放弃Keil&#xff1f; 如果你接触过C51单片机开发&#xff0c;Keil μVision这个名字一定不会陌生。作为单片机开发领域的"老前辈"&#xff0c;Keil几乎成了教学和入门的标准工具。但说实话&#xff0c;每次打开那个灰蒙蒙的界面&#xff0c;我都感觉…...

Restate监控与调试:如何利用内置工具实现应用全链路可观测性

Restate监控与调试&#xff1a;如何利用内置工具实现应用全链路可观测性 【免费下载链接】restate Restate is the platform for building resilient applications that tolerate all infrastructure faults w/o the need for a PhD. 项目地址: https://gitcode.com/gh_mirro…...

Ai人工智能知识补充

文章目录 1.5 数据与算法基础:智能系统的“燃料”与“引擎” 1.5.1 数据工程:从原始数据到模型“燃料”的全链路 1.5.2 算法模型构建:从问题定义到模型部署的“炼金术” 1.5.3 数据隐私与安全:在价值挖掘与权利保护间走钢丝 1.6 面临的主要挑战:通往真正智能之路的险阻 1.…...