当前位置: 首页 > 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;查 …...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...