c++静态数据成员

目录

静态成员变量

1. 问:这是为什么呢? (以下结束均为个人理解,如有问题,请指教)

 2. 使用场景(举一个例子)

 代码中需要注意的点:

3.总结: 

静态成员函数 

使用场景: 

静态成员函数中没有this指针:


static关键字用于定义静态成员,在c中我们也是用它来定义。在c中,当我们想要提升局部变量生命周期 -- 就是函数结束后,不释放其内存。 

c++类中也可以使用静态,主要有两种:  静态成员函数和静态成员变量 

静态成员变量

 使用static定义的成员变量,  这种变量它属于类,不属于某一个对象。但是所有的对象都使用同一片空间。

1. 问:这是为什么呢? (以下结束均为个人理解,如有问题,请指教)

1)静态存储区 

在内存分区中有一个静态全局区,用于存放全局变量和静态变量,它们的生命周期是其定义到程序结束。 

2)static修饰的量 

static修饰的量为静态的,所以这样的变量存放在静态常量区,生命周期到程序结束。

3)定义类对象 

之前说过类对象,其实就是一个特殊的变量,所以它也有生命周期(也就是存储在哪块内存中)。普通的类对象,其实就是一个局部变量,存储在栈区

4)类中的变量 

当我们定义对象的时候,类中也有局部变量,也在栈区存储。上面说对象也在栈区所以这些存储在栈区的量,才是对象所拥有的。(因为都存储在栈区) 

不同对象中的这些数据是不同的,所以,可以理解为,在栈区中每一个对象变量包含了其自己的局部成员变量的空间。 

5)对象共同的

普通局部变量是属于对象的,因为每个对象中的这些量中存储的数据都不同,因为,在栈区中,根据我们创建的对象,它们各自有空间,这些空间用来存储对象自己的成员局部变量的数据。所以,每个对象的数据中的值不同。(因为它们就不是一块内存)。如图:

定义两个对象man1和man2,age,name,salary表示类内非静态数据成员。 

static的成员变量,在静态常量区,和对象不在一个区,所以整个类这份数据只有一份(也就是都是一块内存)。 所以对于静态成员,所有对象使用的都是同一片内存。

 2. 使用场景(举一个例子)

当我们需要统计我们定义的变量个数的时候, 就可以使用静态的成员变量。

class Human {
public:
	Human();
	Human(int age,string name);
	int getCount();  // 提供接口可以获取Count的值
private:
	int age;
	string name;
	static int Count;  // 用来记录创建对象的个数
};

// 静态数据使用是需要初始化
int Human::Count = 0;  // 对类的静态数据进行初始化,只能在类外进行初始化

/*因为创建一个对象,就需要调用一种构造函数,所以我们在每一类构造函数中都对Count+1*/
Human::Human(int age, string name) {
	this->age = age;
	this->name = name;
	Count++;
}

Human::Human() {
	age = 10;
	name = "学习";
	Count++;
}

int Human::getCount() {
	return Count;
}

// 测试函数
void test() {
	Human man1(10,"学习");
	Human man2;
}

int main(void) {
	Human man1;
	test();

	cout << man1.getCount() << endl;

	system("pause");

	return 0;
}
 代码中需要注意的点:

1)  因为count只有一片空间,每次都是对一个数据进行+1,所以可以得到对象被创建的个数。

2)  static的量初始化,必须在类外进行初始化,不能在类内初始化(类内初始化会出错)。当然也只有静态成员变量可以在类外部初始化。 

3)  如果要求严谨,也可以在析构函数中将count-1。 

3.总结: 

其实使用静态成员是不用想太多,  知道所有对象使用同一份数据就行。

静态成员函数 

和静态成员变量,它是属于类的。每个对象共有。 

class Human {
public:
	Human();
	Human(int age,string name);
	static int getCount();  
private:
	int age;
	string name;
	static int Count; 
};


int main(void) {
	Human man1;
	test();

	cout << Human::getCount() << endl;  // 可以直接使用类名调用

	system("pause");

	return 0;
}

静态成员函数可以在类外直接使用类名进行调用。 

使用场景: 

静态成员变量的弊端: 

在我们使用静态成员变量的时候,我们想要获取它的值必须,定义一个对象调用其接口,才能得到值。

有时候,我们在调用类内函数的时候,可能并不想创建对象,这时候就可以将此函数定义成静态的。  ---------  可以在类外直接使用类名调用,不需要创建对象。(当然使用对象名调也可以)。 

静态成员函数中没有this指针:

首先,this指针是用来指向当前调用的函数的,而静态成员函数是所有对象共有,所以它不需要使用this来指向调用者。(比如学校的宿舍和水房,宿舍有门牌号,但是水房是共有的就不需要门牌号了)

既然没有this指针,那么在静态函数的内部也就无法访问非静态成员变量。 因为,它无法区分这个变量是哪个对象的。

所以,静态成员函数中只能访问静态成员变量因为,静态成员变量也是共有的,就不需要this指针。 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大模型核心技术原理: Transformer架构详解

在大模型发展历程中&#xff0c;有两个比较重要点&#xff1a;第一&#xff0c;Transformer 架构。它是模型的底座&#xff0c;但 Transformer 不等于大模型&#xff0c;但大模型的架构可以基于 Transformer&#xff1b;第二&#xff0c;GPT。严格意义上讲&#xff0c;GPT 可能…

Linux 内核如何根据设备树文件来匹配内核

一. 简介 上一篇文章学习了 Linux内核如何确定是否支持此设备&#xff0c;如果支持&#xff0c;设备就会启动 Linux 内核。 文章地址如下&#xff1a; 设备树根节点下的compatile属性的作用-CSDN博客 本文继上面文章的学习。这里简单看一下&#xff0c; Linux 内核是如何根…

odoo17 | 模型之间的交互

前言 在前一章中&#xff0c;我们使用继承来修改模块的行为。在我们的房地产场景中&#xff0c;我们希望更进一步&#xff0c;能够为我们的客户生成发票。Odoo提供了一个发票&#xff08;Invoicing&#xff09;模块&#xff0c;所以直接从我们的房地产模块创建一个发票会很简洁…

VS报错:error:LNK2005 _main 已经在 *.obj 中定义

应该是重定义了&#xff0c;但是又解决不了&#xff0c;看似又没有重定义啊&#xff0c;就在一个文件定义了啊&#xff1f;怎么会出现这种情况呢&#xff1f;关键是&#xff0c;编译报错&#xff0c;程序运行不了了。 这里提一下我的前期操作&#xff0c;是因为将一个头文件和…

图像监视:在 Visual Studio 调试器中查看内存中图像

先决条件 本教程假定您具有以下可用项&#xff1a; 安装了 Update 1 的 Visual Studio 2012 Professional&#xff08;或更高版本&#xff09;。更新 1 可在此处下载。在 Windows 计算机上安装 OpenCV&#xff08;教程&#xff1a;在 Windows 中安装&#xff09;。能够在 Visua…

【Spring 篇】深入探索:Spring集成Web环境的奇妙世界

嗨&#xff0c;亲爱的小白们&#xff01;欢迎来到这篇有关Spring集成Web环境的博客。如果你曾对如何在Spring中构建强大的Web应用程序感到好奇&#xff0c;那么这里将为你揭示Web开发的神秘面纱。我们将用情感丰富、语句通顺的文字&#xff0c;以小白友好的方式&#xff0c;一探…

survey和surveyCV:如何用R语言进行复杂抽样设计、权重计算和10折交叉验证?

一、引言 在实际调查和研究中&#xff0c;我们往往面临着样本选择的复杂性。复杂抽样设计能够更好地反映真实情况&#xff0c;提高数据的代表性和可靠性。例如&#xff0c;多阶段抽样可以有效地解决大规模调查的问题&#xff0c;整群抽样能够在保证样本的随机性的同时减少资源消…

D25XB100-ASEMI家用电器整流桥D25XB100

编辑&#xff1a;ll D25XB100-ASEMI家用电器整流桥D25XB100 型号&#xff1a;D25XB100 品牌&#xff1a;ASEMI 封装&#xff1a;GBJ-5&#xff08;带康铜丝&#xff09; 平均正向整流电流&#xff08;Id&#xff09;&#xff1a;25A 最大反向击穿电压&#xff08;VRM&…

thinkphp递归实现无限级子分类合并上级children

//设别分类列表public function getCategoryList(){$list = Db::name(categorys)->select(

玩转Mysql 七 (索引的创建与设计原则)

一、索引的创建与使用 1、索引的分类 MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。 &#xff08;1&#xff09;从 功能逻辑 上说&#xff0c;索引主要有 4 种&#xff0c;分别是普通索引、唯一索引、主键索引、全文索引。 &#xff08;…

20_GC垃圾回收机制

文章目录 GC如何确定垃圾如何回收垃圾回收垃圾的时机 GC 如何确定垃圾 引用计数算法 给对象添加一个引用计数器&#xff0c;每当一个地方引用它时&#xff0c;计数器加1&#xff0c;每当引用失效时&#xff0c;计数器减少1&#xff0c;当计数器的数值为0时&#xff0c;也就是对…

Django教程|数据统计图表(echarts、highchart)

前言 highchart&#xff0c;国外。 echarts&#xff0c;国内。 本项目集成 hightchart和echarts图表库实现数据统计功能。 包括&#xff1a;折线图&#xff0c;柱状图&#xff0c;饼图和数据集图。 效果图 echats Highcharts 源代码 编写模板&#xff08;Template&#x…

Docker安装Atlassian全家桶

文章目录 省流&#xff1a;1.docker-compose文件2.其他服务都正常启动&#xff0c;唯独Bitbucket不行。日志错误刚启动时候重启后查询分析原因再针对第一点排查看样子是安装的bitbucket和系统环境有冲突问题&#xff1f; 结论&#xff1a; 省流&#xff1a; bitbucket 只能安装…

idea使用ssh连接docker,并通过Dockerfile文件,直接在idea中启动docker应用,并进行远程debug

idea使用ssh连接docker&#xff0c;并通过Dockerfile文件&#xff0c;直接在idea中启动docker应用&#xff0c;并进行远程debug 第一步: idea通过ssh连接docker第二步&#xff1a;使用Dockerfile文件在远程启动应用第三步: 远程debug 容器运行的好处是减轻本地运行的负担(本地电…

数据结构初探:揭开数据结构奥秘

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、算法模板、汇编语言 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 数组结构起源二. 基本概念和术语2.1 数据2.2 数据元素2.3 数据项2.4 …

Rust-语句和表达式

if-else Rust中if-else表达式的作用是实现条件分支。if-else表达式的构成方式为&#xff1a;以if关键字开头&#xff0c;后面跟上条件表达式&#xff0c;后续是结果语句块&#xff0c;最后是可选的else块。条件表达式的类型必须是bool。 if-else结构还可以当表达式使用 loop …

苹果手机怎么恢复备份?详细攻略为你整理好了!

随着智能手机和互联网的普及&#xff0c;手机中存储的个人信息、照片、视频、聊天记录等数据会变得越来越多。一旦手机丢失、损坏或系统出现问题&#xff0c;我们很可能会面临数据丢失的风险。因此&#xff0c;越来越多的人开始意识到保护手机数据的重要性。 当苹果手机数据丢…

Mnajora 使用deb包安装软件

说明 Mnajora 安装deb软件包主要有两种方式 可以使用dpkg 直接安装也可是使用debtap将deb软件包转换成 使用dpkg sudo pacman -S dpkg #安装dpkgsudo dpkg -i ###.deb #使用dpkg安装deb软件包和在ubuntu上是一样的 安装成功 使用debtap debtap是一个用于将.deb包转换为A…

C++力扣题目617--合并二叉树

给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xff0c;两棵树上的一些节点将会重叠&#xff08;而另一些不会&#xff09;。你需要将这两棵树合并成一棵新二叉树。合并的规则是&#xff1a;如果两个节点重叠&#…

“+”连接符用法(Java)

""可以作为连接符使用&#xff0c;如果与字符串一起运算&#xff0c;结果依旧是一个字符串 比如"aaa"6 --> "aaa6" 在打印中&#xff0c;能算就算&#xff0c;不能计算的时候就会连接在一起 注意先后顺序 ascii编码&#xff1a; 字符串&…