【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++ 提供了三个访问限定符,public、private、protected。
public修饰的成员可以在类外访问,private和protected修饰的成员不能在类外访问。
class的默认访问权限为private,struct为public。
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 语言中,我们用结构体来描述一个事物的多种属性…...
【Linux命令200例】indent对C语言代码进行缩进和格式化
🏆作者简介,黑夜开发者,全栈领域新星创作者✌,2023年6月csdn上海赛道top4。 🏆本文已收录于专栏:Linux命令大全。 🏆本专栏我们会通过具体的系统的命令讲解加上鲜活的实操案例对各个命令进行深入…...
Hive 调优集锦(1)
一、前言 1.1 概念 Hive 依赖于 HDFS 存储数据,Hive 将 HQL 转换成 MapReduce 执行,所以说 Hive 是基于Hadoop 的一个数据仓库工具,实质就是一款基于 HDFS 的 MapReduce 计算框架,对存储在HDFS 中的数据进行分析和管理。 1.2 架…...
【C++详解】——智能指针
目录 为什么需要智能指针 抛异常引发内存泄漏 内存泄漏 什么是内存泄漏,内存泄漏的危害 内存泄漏分类 检测内存泄漏常用工具 如何避免内存泄漏 智能指针的使用及原理 RAII 智能指针的原理 各类智能指针介绍 auto_ptr unique_ptr shared_ptr weak_ptr …...
Jmeter接口/性能测试,Jmeter使用教程(超细整理)
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 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 展示上传图片缩略图(本地图片读取)
需求: 点击上传图片按钮,选择图片以后,不请求后端接口,直接将图片展示在缩略图中。 解决方案: 使用 FileReader 和 FileReader 中的 readAsDataURL 方法。 第一步 从input[type“file”] (上传文件标签) 里面拿到fil…...
Vue中$route和$router的区别
$router:用来操作路由,$route:用来获取路由信息 $router其实就是VueRouer的实例,对象包括了vue-router使用的实例方法,还有实例属性,我们可以理解为$router有一个设置的含义,比如设置当前的跳转…...
基于多任务学习卷积神经网络的皮肤损伤联合分割与分类
文章目录 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例程(1)环形串口缓冲区结构体(2)串口环形缓冲区存和取数据(3)完整工程demo 一、串口环形缓冲区概念 串口环形缓冲区应用于嵌入式、物联网开发中处理接收串口数据…...
【腾讯云 Cloud Studio 实战训练营】基于Cloud Studio完成简易通讯录
目录 🔆Cloud Studio 简介 操作步骤 1.登录 2.创建工作空间 3.初始界面 4.开发空间 5.保存自定义模板 🔆简易通讯录 1.实验要求 2.操作环境 3.源代码介绍 3.1 定义通讯录类 3.2 定义通讯录列表 3.3 添加联系人功能 3.4 修改联系人 3.5 …...
【技术积累】Vue.js中的核心知识
Vue的生命周期 Vue中的生命周期是指组件从创建到销毁的整个过程中,会触发一系列的钩子函数 Vue2中的生命周期 Vue2中的生命周期钩子函数是在组件的不同阶段执行的特定函数。这些钩子函数允许开发者在组件的不同生命周期阶段执行自定义的逻辑。 Vue2中的生命周期钩…...
flutter开发实战-显示本地图片网络图片及缓存目录图片
flutter开发实战-显示本地图片网络图片及缓存目录图片 在最近开发中碰到了需要显示缓存目录图片,这里顺便整理一下,显示本地图片、网络图片、缓存目录图片的方法。 一、工程本地图片显示 1 在项目根目录下创建名为 images文件夹,也可以将i…...
面对未来的算法备案法规:企业需要做哪些准备?
在信息时代,算法已经成为我们生活的一部分,涵盖了诸如搜索引擎、社交媒体、电子商务、广告投放等各个方面。然而,随着算法的广泛应用,其带来的问题也日益凸显。这引发了全球范围内的关注,未来的算法备案法规正在酝酿之…...
iptables的备份和还原
iptables的备份和还原 1、写在命令行当中的都是临时设置 2、把规则配置写在服务的文件当中,形成永久有效 备份:把iptables里面所有的配置都保存在/opt/ky30.bak中 iptables-save > /opt/ky30.bak 例: 默认配置文件在/etc/sysconfig/ip…...
easyUI框架学习
文章目录 一、前言二、引入使用easyUI 三、用法3.1 Dialog(对话框窗口)3.1.1 示例13.1.2 示例2 3.2 Layout(布局)3.2.1 示例1——通过标签创建布局3.2.2 示例2—— 创建嵌套布局 3.3 DateBox(日期输入框)3.…...
加入气压计模组,星斗3号将实现快速三维定位
随着信息技术的飞速发展,人们的生活正在发生巨大改变,人们对基于位置服务的需求越来越迫切,尤其是室内位置服务。 室外定位系统中BDS系统、GPS系统等受室内复杂环境条件限制精度大幅下降甚至失效,难以在室内定位中发挥作用,而室内二维定位技术缺乏高程信息,也难以满足人们对室…...
华为HCIP第二节-------------------------ISIS
IS-IS(Intermediate System to Intermediate System,中间系统到中间系统)是ISO (International Organization for Standardization,国际标准化组织)为它的CLNP(ConnectionLessNetwork Protocol&…...
在Mac系统下搭建Selenium环境并驱动Chrome浏览器
本文带领那些使用Mac的童鞋们实现Selenium驱动Chrome浏览器,虽然会有坑,但是我们可以凭借敏捷的身手躲过。下面就开始吧: 安装selenium 打开终端 ->pip安装(安装命令:pip3 install selenium) 安装浏览…...
通过RPM方式安装,升级,卸载,以及配置使用MySQL
通过RPM方式安装,升级,卸载,以及配置使用MySQL 一、下载 MySQL是一种开源的关系数据库管理系统,被广泛应用于各种业务应用中。本文将讲解如何下载和安装MySQL的rpm安装包。 下载rmp安装包有多种方式: 1、官网下载 …...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
41道Django高频题整理(附答案背诵版)
解释一下 Django 和 Tornado 的关系? Django和Tornado都是Python的web框架,但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。它遵循MVC设计,并强调代码复用。Django有…...
