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

【C++面向对象编程】(二)this指针和静态成员

文章目录

  • this指针和静态成员
    • this指针
    • 静态成员

this指针和静态成员

this指针

C++中类的成员变量和成员函数的存储方式有所不同:

  • 成员变量:对象的成员变量直接作为对象的一部分存储在内存中。
  • 成员函数:成员函数(非静态成员函数)不直接存储在对象的内存中。它们的代码(即函数体中的指令)存储在代码区中。

当我们创建一个类的多个对象时,这些对象的成员函数的代码是共享的,也就是说,无论我们创建多少个类的对象,这些函数的代码都只有一份。 但是,每个对象都有自己独立的成员变量。为了在这些共享的成员函数内部引用和修改特定对象的成员变量,C++提供了this指针。this指针是一个隐式的指针,它指向调用非静态成员函数的对象。

示例

#include <iostream>  class MyClass {  
private:  int myVar; public:  MyClass(int value) : myVar(value) {}void printMyVar() {  std::cout << "The value of myVar for this object is: " << this->myVar << std::endl;  // this-> 可以不显式声明,编译器会自动为你处理.this->myVar可以改成myVar}  void setMyVar(int newValue) {  this->myVar = newValue; // 使用this指针来引用当前对象的myVar }  
};  int main() {  MyClass obj1(10);MyClass obj2(20);obj1.printMyVar(); // The value of myVar for this object is: 10  obj2.printMyVar(); // The value of myVar for this object is: 20  obj1.setMyVar(30); obj1.printMyVar(); // The value of myVar for this object is: 30  obj2.printMyVar(); // The value of myVar for this object is: 20,第二个对象的myVar保持不变  return 0;  
}

在这个例子中,MyClass类的两个成员函数:printMyVarsetMyVar都通过this指针来引用和修改当前对象的成员变量。

在类的成员函数内部中,通常不需要显式声明this指针,因为编译器会自动处理。然而,在某些情况下,可以显式地使用this指针,例如:

  • 通过this指针区分成员变量和参数。
  • 通过this指针返回调用对象本身,实现链式调用。

示例

#include<iostream>
class MyClass {
private:int x;public:MyClass(int value) : x(value) {}// 使用this指针来区分成员变量和参数void setValue(int x) {this->x = x; }// 使用this指针返回调用对象本身MyClass& increment() {this->x++;return *this; // 返回*this即返回调用对象本身}int getValue() const {return x; }
};int main() {MyClass obj(5);obj.setValue(20);obj.increment().increment(); // 链式调用std::cout << obj.getValue() << std::endl; // 输出22return 0;
}

静态成员

类的非静态成员(包括成员变量和成员函数)是类的每个对象所独有的。每一个类的对象会拥有自己独立的内存空间来存储其非静态成员变量的值,并通过this指针来与非静态成员函数进行关联。每个对象在调用非静态成员函数时,都会通过this指针传递自己的地址给该函数,以便函数能够访问和修改该对象的成员变量。

类的静态成员(包括静态成员变量和静态成员函数)在所有类的对象之间是共享的,只存在于一个数据存储区域。静态成员不与类的任何特定对象相关联。因此,静态成员函数内部没有this指针的概念。

静态数据成员: 在类的所有对象之间共享其值。在C++17之前,静态数据成员只能在类外进行初始化。C++17之后可以使用内联关键字inline 在类内初始化静态数据成员。

类外初始化静态数据成员:

class MyClass {
public:static int count; // 声明静态数据成员MyClass() {count++; }~MyClass() {count--; }
};// 在类外初始化静态数据成员
int MyClass::count = 0;int main() {MyClass obj1; // 构造时,count 增加到 1MyClass obj2; // 构造时,count 增加到 2std::cout << MyClass::count << std::endl; // 输出 2return 0;
}

使用C++17新增的inline 在类内初始化静态数据成员:

#include <iostream>  class MyClass {  
public:  // 使用内联变量语法在类内部声明并初始化静态数据成员inline static int count = 0;MyClass() {  count++;}  ~MyClass() {  count--; }  
};  int main() {  MyClass obj1; // 构造时,count 增加到 1  MyClass obj2; // 构造时,count 增加到 2  std::cout << MyClass::count << std::endl; // 输出 2  return 0;  
}

静态成员函数: 可以通过任何对象的实例或类名来调用,但是不能访问类的非静态成员。

#include <iostream>  
#include <string>  class MyClass {  
private:  int nonStaticVar; // 非静态成员变量  inline  static int staticVar = 42; // 静态成员变量public:  MyClass(int value) : nonStaticVar(value) {}  // 静态成员函数  static void printStaticVar() {  std::cout << "The value of staticVar is: " << staticVar << std::endl;  // 尝试通过静态成员函数访问非静态成员变量会导致编译错误  // std::cout << "The value of staticVar is: " << nonStaticVar << std::endl;  }  // 非静态成员函数  void printVars() {  std::cout << "The value of staticVar is: " << staticVar << std::endl;  std::cout << "The value of nonStaticVar is: " << nonStaticVar << std::endl;  }  
};  int main() {  MyClass obj(10);  // 通过类名调用静态成员函数  MyClass::printStaticVar();   // The value of staticVar is: 42 // 通过对象实例调用静态成员函数obj.printStaticVar();  // The value of staticVar is: 42 // 调用非静态成员函数  obj.printVars();   // The value of staticVar is: 42   //The value of nonStaticVar is: 10return 0;  
}

相关文章:

【C++面向对象编程】(二)this指针和静态成员

文章目录 this指针和静态成员this指针静态成员 this指针和静态成员 this指针 C中类的成员变量和成员函数的存储方式有所不同&#xff1a; 成员变量&#xff1a;对象的成员变量直接作为对象的一部分存储在内存中。成员函数&#xff1a;成员函数&#xff08;非静态成员函数&am…...

最大矩形问题

柱状图中最大的矩形 题目 分析 矩形的面积等于宽乘以高&#xff0c;因此只要能确定每个矩形的宽和高&#xff0c;就能计算它的面积。如果直方图中一个矩形从下标为 i 的柱子开始&#xff0c;到下标为 j 的柱子结束&#xff0c;那么这两根柱子之间的矩形&#xff08;含两端的柱…...

LeetCode62不同路径

题目描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。问总共有多少条不同的路径&#xff1f; …...

GNU Radio实现OFDM Radar

文章目录 前言一、GNU Radio Radar Toolbox编译及安装二、ofdm radar 原理讲解三、GNU Radio 实现 OFDM Radar1、官方提供的 grc①、grc 图②、运行结果 2、修改后的便于后续可实现探测和通信的 grc①、grc 图②、运行结果 四、资源自取 前言 本文使用 GNU Radio 搭建 OFDM Ra…...

东方博宜1760 - 整理抽屉

题目描述 期末考试即将来临&#xff0c;小T由于同时肩负了学习、竞赛、班团活动等多方面的任务&#xff0c;一直没有时间好好整理他的课桌抽屉&#xff0c;为了更好地复习&#xff0c;小T首先要把课桌抽屉里的书分类整理好。 小T的抽屉里堆着 N 本书&#xff0c;每本书的封面上…...

react快速开始(四)-之Vite 还是 (Create React App) CRA? 用Vite创建项目

文章目录 react快速开始(四)-之Vite 还是 (Create React App) CRA? 用Vite创建项目背景Vite 和 (Create React App) CRAVite&#xff1f;Vite 是否支持 TypeScript&#xff1f; 用Vite创建react项目参考 react快速开始(四)-之Vite 还是 (Create React App) CRA? 用Vite创建项…...

使用python绘制核密度估计图

使用python绘制核密度估计图 核密度估计图介绍效果代码 核密度估计图介绍 核密度估计&#xff08;Kernel Density Estimation&#xff0c;KDE&#xff09;是一种用于估计数据概率密度函数的非参数方法。与直方图不同&#xff0c;KDE 可以生成平滑的密度曲线&#xff0c;更好地…...

5. MySQL 运算符和函数

文章目录 【 1. 算术运算符 】【 2. 逻辑运算符 】2.1 逻辑非 (NOT 或者 !)2.2 逻辑与运算符 (AND 或者 &&)2.3 逻辑或 (OR 或者 ||)2.4 异或运算 (XOR) 【 3. 比较运算符 】3.1 等于 3.2 安全等于运算符 <>3.3 不等于运算符 (<> 或者 !)3.4 小于等于运算符…...

Linux学习之vi文本编辑器的使用

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…...

【数据结构】链表与顺序表的比较

不同点&#xff1a; 顺序表和链表是两种常见的数据结构&#xff0c;他们的不同点在于存储方式和插入、删除操作、随机访问、cpu缓存利用率等方面。 一、存储方式不同: 顺序表&#xff1a; 顺序表的存储方式是顺序存储&#xff0c;在内存中申请一块连续的空间&#xff0c;通…...

dart 基本语法

//入口方法 main() 或 void main() //数据类型 原生数据类型 String int double bool null 注意&#xff1a;String 包函 ‘’ “” ‘’’ ‘’’ 三种形式复杂数据类型 list Set Map自定义数据类型 class inheritance动态数据类型 var 注&#xff1a;dart 是静态类型语言&a…...

【经验分享】嵌入式入坑经历(选段)

文章目录 你现在的工作中所用到的专业知识有哪些呢&#xff1f;为什么想转行了&#xff1f;后来为什么从事了嵌入式行业呢?你对嵌入式的兴趣是何时培养起来的?你是怎么平衡兴趣爱好和工作的关系的?平时做的事情对你现在的工作有哪些帮助?对于有志学习嵌入式开发的在校大学生…...

Docker面试整理-Docker与虚拟机的区别是什么?

Docker 容器和传统的虚拟机(VM)都是提供隔离的运行环境以部署和运行应用程序的技术,但它们在架构和性能上存在显著的不同。了解这些差异可以帮助你选择最适合特定需求的解决方案: 基础架构:虚拟机:每个虚拟机都包括完整的操作系统、应用程序、必需的库和二进制文件,运行在…...

Java:JDK8 GC中ParNew和CMS的问题说明

JDK8中常用如下的垃圾收集器&#xff0c;它们分别运用在年轻代和老年代&#xff1a; ParNew : 年轻代垃圾收集器&#xff0c;多线程&#xff0c;采用标记—复制算法。 CMS&#xff1a;老年代的收集器&#xff0c;全称&#xff08;Concurrent Mark and Sweep&#xff09;&#…...

学单片机前先学什么?

先学c语言和数字电路 这里默认你说的单片机是51单片机&#xff0c;通过你的问题&#xff0c;我猜你的单片机应该还没有入门&#xff0c;如果是入门的话&#xff0c;一般都是从51单片机开始的。刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从…...

数据可视化:Matplotlib 与 Seaborn

数据可视化是数据分析中至关重要的一部分&#xff0c;它能帮助我们直观地理解数据的分布、趋势和关系。Python 中&#xff0c;Matplotlib 和 Seaborn 是两个最常用的可视化库。本文将详细介绍如何使用 Matplotlib 和 Seaborn 进行数据可视化&#xff0c;包括基本图形、图形定制…...

【linux】自定义快捷命令/脚本

linux自定义快捷命令 场景自定义命令自定义脚本 场景 深度学习经常要切换到自己环境&#xff0c;conda activate mmagic&#xff0c;但是又不想每次重复打这么多字&#xff0c;想使用快捷命令直接切换。 自定义命令 使用别名&#xff08;alias&#xff09;或自定义脚本来创建…...

使用onnxruntime加载YOLOv8生成的onnx文件进行目标检测

在网上下载了60多幅包含西瓜和冬瓜的图像组成melon数据集&#xff0c;使用 LabelMe 工具进行标注&#xff0c;然后使用 labelme2yolov8 脚本将json文件转换成YOLOv8支持的.txt文件&#xff0c;并自动生成YOLOv8支持的目录结构&#xff0c;包括melon.yaml文件&#xff0c;其内容…...

QT 信号和槽 一对多关联示例,一个信号,多个槽函数响应,一个信号源如何绑定多个槽函数

在窗体里放置一个单行文本编辑控件&#xff08;QLineEdit&#xff09;、一个标签控件&#xff08;QLabel&#xff09;和一个文本浏览控件&#xff08;QTextBrowser&#xff09;&#xff0c;在单行文 本编辑控件里的文本被编辑时&#xff0c;标签控件和文本浏览控件都会同步显示…...

C++ AVL树 详细讲解

目录 一、AVL树的概念 二、AVL树的实现 1.AVL树节点的定义 2.AVL树的插入 3.AVL树的旋转 4.AVL树的验证 三、AVL树的性能 四、完结撒❀ 一、AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但 如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查 …...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...