C++ static静态成员变量

在C++中,我们可以使用静态成员变量来实现多个对象共享数据的目标。静态成员变量是一种特殊的成员变量,它被关键字static修饰,例如:

class Student{
public:Student(char *name, int age, float score);void show();
public:static int m_total;  //静态成员变量
private:char *m_name;int m_age;float m_score;
};

这段代码声明了一个静态成员变量 m_total,用来统计学生的人数。

static 成员变量属于类,不属于某个具体的对象,即使创建多个对象,也只为 m_total 分配一份内存,所有对象使用的都是这份内存中的数据。当某个对象修改了 m_total,也会影响到其他对象。

static 成员变量必须在类声明的外部初始化,具体形式为:

type class::name = value;

type 是变量的类型,class 是类名,name 是变量名,value 是初始值。将上面的 m_total 初始化:

int Student::m_total = 0;

静态成员变量在初始化时不能再加 static,但必须要有数据类型。被 private、protected、public 修饰的静态成员变量都可以用这种方式初始化。

注意:static 成员变量的内存既不是在声明类时分配,也不是在创建对象时分配,而是在(类外)初始化时分配。反过来说,没有在类外初始化的 static 成员变量不能使用。

static 成员变量既可以通过对象来访问,也可以通过类来访问。请看下面的例子:

//通过类类访问 static 成员变量
Student::m_total = 10;//通过对象来访问 static 成员变量
Student stu("小明", 15, 92.5f);
stu.m_total = 20;//通过对象指针来访问 static 成员变量
Student *pstu = new Student("李华", 16, 96);
pstu -> m_total = 20;

这三种方式是等效的。

注意:static 成员变量不占用对象的内存,而是在所有对象之外开辟内存,即使不创建对象也可以访问。

下面来看一个完整的例子:

#include <iostream>
using namespace std;class Student{
public:Student(char *name, int age, float score);void show();
private:static int m_total;  //静态成员变量
private:char *m_name;int m_age;float m_score;
};//初始化静态成员变量
int Student::m_total = 0;Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){m_total++;  //操作静态成员变量
}
void Student::show(){cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<"(当前共有"<<m_total<<"名学生)"<<endl;
}int main(){//创建匿名对象(new Student("小明", 15, 90)) -> show();(new Student("李磊", 16, 80)) -> show();(new Student("张华", 16, 99)) -> show();(new Student("王康", 14, 60)) -> show();return 0;
}

运行结果:

小明的年龄是15,成绩是90(当前共有1名学生)
李磊的年龄是16,成绩是80(当前共有2名学生)
张华的年龄是16,成绩是99(当前共有3名学生)
王康的年龄是14,成绩是60(当前共有4名学生)

上例中将 m_total 声明为静态成员变量,每次创建对象时,会调用构造函数使 m_total 的值加 1。

之所以使用匿名对象,是因为每次创建对象后只会使用它的 show() 函数,不再进行其他操作。不过使用匿名对象无法回收内存,会导致内存泄露,在中大型程序中不建议使用。

解析说明

1 一个类中可以有一个或多个静态成员变量,所有的对象都共享这些静态成员变量,都可以引用它。

2 static 成员变量和普通 static 变量一样,都在内存分区中的全局数据区分配内存,到程序结束时才释放。这就意味着,static 成员变量不随对象的创建而分配内存,也不随对象的销毁而释放内存。而普通成员变量在对象创建时分配内存,在对象销毁时释放内存。

3 静态成员变量必须初始化,而且只能在类体外进行。例如:

int Student::m_total = 10;

初始化时可以赋初值,也可以不赋值。如果不赋值,那么会被默认初始化为 0。

4 静态成员变量既可以通过对象名访问,也可以通过类名访问,但要遵循 private、protected 和 public 关键字的访问权限限制。当通过对象名访问时,对于不同的对象,访问的是同一份内存。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle河南城建学院实验报告,数据处理实验报告

化工与材料工程学院实验报告《试验设计与数据处理》上机实验报告学 生 学 号 学 生 姓 名 专 业 班 级 指 导 教 师 联合指导教师 完 成 日 期教 授 教 授 2010.5.27.第 1 章 实验一 Excel 基础及有关操作技巧1.1 实验目的熟悉 Excel 基础操作&#xff0c;掌握 Excel 有关操作技…

import lombok 报错_Lombok注解@Getter @Setter详解

1.为什么强大​项目中经常使用bean&#xff0c;entity等类&#xff0c;绝大部分数据类类中都需要get、set、toString、equals和hashCode方法&#xff0c;尽管IDE工具都会帮我们生成。但自动生成这些代码后&#xff0c;如果bean中的属性一旦有修改、删除或增加时&#xff0c;需要…

司铭宇老师:如何让企业销售培训效果落地

如何让企业销售培训效果落地 在企业销售培训中&#xff0c;我们经常听到一个词&#xff0c;那就是“落地”。所谓的“落地”&#xff0c;简单来说就是将培训中所学到的知识和技能转化为实际的工作行动&#xff0c;从而提高销售业绩。但是&#xff0c;如何才能让销售培训效果真…

C++ static静态成员函数

在类中&#xff0c;static 除了可以声明静态成员变量&#xff0c;还可以声明静态成员函数。普通成员函数可以访问所有成员&#xff08;包括成员变量和成员函数&#xff09;&#xff0c;静态成员函数只能访问静态成员。 编译器在编译一个普通成员函数时&#xff0c;会隐式地增加…

php7开发的项目怎么样,如何在PHP7项目中搭建一个多线程

如何在PHP7项目中搭建一个多线程发布时间&#xff1a;2021-03-05 15:31:22来源&#xff1a;亿速云阅读&#xff1a;93作者&#xff1a;Leah这期内容当中小编将会给大家带来有关如何在PHP7项目中搭建一个多线程&#xff0c;文章内容丰富且以专业的角度为大家分析和叙述&#xff…

C++ const成员变量和成员函数

const成员变量 const 成员变量的用法和普通 const 变量的用法相似&#xff0c;只需要在声明时加上 const 关键字。初始化 const 成员变量只有一种方法&#xff0c;就是通过构造函数的初始化列表。 const成员函数&#xff08;常成员函数&#xff09; const 成员函数可以使用类…

通过日志恢复oracle序列,(存档日志包含序列84,要求序列36)怎么恢复啊?

(存档日志包含序列84&#xff0c;要求序列36)怎么恢复啊&#xff1f;SQL> startup mount;ORACLE 例程已启动Total System Global Area 135338868 bytesFixed Size 453492 bytesVariable Size 109051904 bytesDatabase Buffers 251…

C++ const对象

C 中&#xff0c;const 也可以用来修饰对象&#xff0c;称为常对象。一旦将对象定义为常对象之后&#xff0c;就只能调用类的 const 成员&#xff08;包括 const 成员变量和 const 成员函数&#xff09;了。 定义常对象的语法和定义常量的语法类似&#xff1a; const class …

lvs工作在第几层_LVS 原理(调度算法、四种模式、四层负载均衡和七层 的区别)...

目录lvs的调度算法lvs的四种模式四层均衡负载和七层的区别1、lvs调度算法(最常用的四种)轮叫调度(rr)调度器通过外部请求的顺序轮流分配到集群中的真实服务器上&#xff0c;对每台服务器都是均等的&#xff1b;但是这样调度器不会考虑服务器上实际的连接数和系统负载&#xff0…

linux 常用头文件,(常用头文件详解.doc

(常用头文件详解linux常用头文件详解POSIX标准定义的头文件??????? 目录项???????? 文件控制??? 文件名匹配类型??? 路径名模式匹配类型??????? 组文件??? 网络数据库操作??????? 口令文件??? 正则表达式??????? TAR归档值??…

a as as big rat_超好玩!12句英语绕口令,你能一口气读完几句?

绕口令(tongue twister)是一种语言游戏&#xff0c;它是将发音相同、相近等容易混淆的字组成拗口的句子&#xff0c;要求朗读者一口气快速念完而且不能出错&#xff0c;极具趣味。相信很多同学都玩过&#xff0c;假如绕口令也有段位划分的话&#xff0c;你是什么段位&#xff1…

C++ friend关键字

friend 的意思是朋友&#xff0c;或者说是好友&#xff0c;与好友的关系显然要比一般人亲密一些。我们会对好朋友敞开心扉&#xff0c;倾诉自己的秘密&#xff0c;而对一般人会谨言慎行&#xff0c;潜意识里就自我保护。在 C 中&#xff0c;这种友好关系可以用 friend 关键字指…

linux vps 运行exe文件夹,linux 64位下安装wine1.6 Windows模拟器(用来运行.exe文件) 编译安装32位wine...

cdyum groupinstall Development Tools -yyum install libX11-devel freetype-devel -ywget http://prdownloads.sourceforge.NET/wine/wine-1.6.tar.bz2tar -jvxf wine-1.6.tar.bz2cd wine-1.6编译之前先安装32位运行库不然不能编译:yum install alsa-lib-devel.i686 libsndfi…

python修改文件格式为unix_软件测试技术之如何用python在Windows系统下,生成UNIX格式文件...

本文将带你了解软件测试技术之如何用python在Windows系统下&#xff0c;生成UNIX格式文件&#xff0c;希望对大家学测试技术有所帮助如何用python在Windows系统下&#xff0c;生成UNIX格式文件平时测试工作中&#xff0c;少不了制造测试数据。最近一个项目&#xff0c;我就需要…

C++ class和struct的区别

C中的 struct 和 class 的区别&#xff1a; 1 . 使用 class 时&#xff0c;类中的成员默认都是 private 属性的&#xff1b;而使用 struct 时&#xff0c;结构体中的成员默认都是 public 属性的。 2 . class 继承默认是 private 继承&#xff0c;而 struct 继承默认是 public …

linux 宽字符串,C语言中的多字节字符与宽字符

C语言原本是在英文环境中设计的&#xff0c;主要的字符集是7位的ASCII码&#xff0c;8位的byte(字节)是最常见的字符编码单位。但是国际化软件必须能够表示不同的字符&#xff0c;而这些字符数量庞大&#xff0c;无法使用一个字节编码。C95标准化了两种表示大型字符集的方法&am…

step7db块寻址_step7 根据db地址块怎样找I/O点

楼主是想在数据块DB中查找呢还是想在FC/FB或OB块中查找呢&#xff1f;如果是在数据块DB中查找&#xff0c;打开希望查找的数据块&#xff0c;例如打开数据块DB9&#xff0c;看地址处是1940的数据就是你需要找的DB9.DBD1940。如图1所示。如果是想查找FC/FB或OB块中DB9.DBD1940这…

vue 获取元素下的所有div_vue获取dom元素高度的方法

获取高度&#xff1a;要在钩子mounted里面dom结构生成后去获取dom的高度&#xff0c;宽度&#xff0c;修改样式等操作&#xff01;&#xff01;&#xff01;mounted() {let h window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; //…

execl执行linux命令,execl执行Linux命令

相关函数&#xff1a;execle, execlp, execv, execve, execvp1.表头文件&#xff1a;#include 2.函数定义&#xff1a;int execl(const char *path, const char *arg, ...);execl()用来执行参数path字符串所代表的文件路径&#xff0c; 接下来的参数代表执行该文件时传递的argv…

C++函数编译原理和成员函数的实现

C函数的编译 C中的函数在编译时会根据命名空间、类、参数签名等信息进行重新命名&#xff0c;形成新的函数名。这个重命名的过程是通过一个特殊的算法来实现的&#xff0c;称为 名字编码&#xff08;Name Mangling&#xff09;。 Name Mangling 是一种可逆的算法&#xff0c;…