c语言静态成员变量重名会怎么样,C++中静态成员函数与静态成员变量(static )...

C++中静态成员函数与静态成员变量(static )

这篇介绍了静态成员函数与静态成员变量,是我的读书笔记,我希望它够简短但又比较全面,起到复习的作用。如果有一些C++知识记不清楚了,它可以帮你很快回忆起来。

复习C语言的static关键字

(1)加在局部变量的前面使之成为静态局部变量,作用域还是在函数内部,可是生存周期延长了。

(2)加在全局变量的前面限定该变量作用域为文件作用域,就是说即使其他文件使用了extern扩展作用域也不行。这在C语言的多人项目中非常有用,避免了变量的重名。然而在C++中这一功能已经被命名空间取代,但是为了保持和C语言的兼容,static还是有这样的功能。

(3)加在函数定义或声明的前面,限定函数作用域到文件作用域,也是为了避免多个文件中有重名函数。

当static关键字出现在类中

当static出现在类的定义中便出现了静态成员变量和静态成员函数。静态成员是属于类的,而不是属于某个对象的。即便没有任何一个实例,类的静态成员变量也已经存在了,而且还可能通过“类名::成员名”进行访问。类的静态成员函数也可以用相同的方式调用,在类产生实例之前就调用成员方法,典型应用是实现单例模式。

(1)静态成员变量

静态成员变量本质上是全局变量,但是将和某些类关系紧密的全局变量写到类里面,形式上成为一个整体,更容易理解和维护。所以尽量使用静态成员变量吧,减少全局变量的使用。普通成员变量每个对象都有各自的一份,但是静态成员变量一共只有一份,被所有的本类对象共享。如果使用sizeof运算符计算对象的大小,得到的结果是不包含静态成员变量在内的。

静态成员同样受到private,public等的限制。

静态成员变量的一个典型应用就是用来计数生成的实例的个数。大体思路是设置一个名为num的静态成员变量并初始化为0,在构造函数中++num,析构函数中--num。这样num的值就是当前实例的个数。实际上这也带来了一个隐蔽的bug。看下面的代码:

class CNum {

public:

static int num;

~CNum() { --num; }

CNum() { ++num; }

};

int CNum::num = 0;

void fun(CNum n){ }

int main() {

CNum n;

fun(n);

fun(n);

cout << CNum::num << endl;

return 0;

}

结果:-1

num尽然成了一个负数,难道析构函数比构造函数多调用了一次?实际上不是的。当执行 fun(n); 语句时调用了复制构造函数,这个函数因为我们没有给出实现,所以是用的编译器默认提供的版本,在这个构造函数中并没有++num这条语句,因此少计数了两次(两次调用fun(n))。

解决的方法就是一定要提供自己写的复制构造函数并在函数体中加入 ++num;

(2)静态成员函数

静态成员函数内部不能调用非静态成员函数,原因是,非静态成员函数需要传入一个this指针,这让静态成员函数很为难,它并不知道与之相关的信息,也就无法提供this指针。

静态成员变量的初始化

上面代码中的第8行  int CNum::num = 0; 是静态成员变量的初始化。这可以视为是静态变量的定义(定义的同时初始化,即便不初始化也需要这个定义),而把类内的 static int num; 视为一个声明,这样的理解可以突出这样一个事实:静态成员变量本质上是全局变量。注意在类外定义时加上“类名::”。

对于常量成员变量,我们知道初始化时一定要使用初始化列表,那么当一个变量既是常量又是静态成员时(同时被const和static修饰)要怎么样初始化呢?是像一般的静态成员变量一样在类外定义并初始化,还是像一般的常量成员变量一样使用初始化列表呢?答案时前者,即在类外定义并初始化,在类内声明,就像下面那样:

class CNum {

public:

const static int num;

};

const int CNum::num = 0;

int main() {

CNum n;

return 0;

}

实际上,完全可以把const int 视为一种数据类型,它的地位和int一样。这样理解是有好处的,比如从const int到int需要强制类型转换,把他们看成两种类型,这就自然而然。相应的const char 和char 也应该看成两种类型,就好像它们完全没有什么特殊的关系一样。

另外static const int类型和static const char 类型可以在类内直接初始化,就是说都不需要在类外再次定义,像下面这样:

class CNum {

public:

const static int a = 19;

};

int main() { 8 cout << CNum::a << endl;    //输出19

return 0;

}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

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

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

相关文章

JVM简单学习

jvm与字节码 jvm只需关注字节码文件 jvm由哪些部分构成 1.类加载子系统&#xff0c;将磁盘中的字节码文件加载到方法区的内存空间中 类加载器分两种&#xff1a;引导类加载器是jvm底层中用C和C语言写的 各个默认的类加载器的不同区别在于 各自默认负责要加载的类的目录不一…

谈一谈自己对依赖、关联、聚合和组合之间区别的理解

在学习面向对象设计对象关系时&#xff0c;依赖、关联、聚合和组合这四种关系之间区别比较容易混淆。特别是后三种&#xff0c;仅仅是在语义上有所区别&#xff0c;所谓语义就是指上下文环境、特定情景等。他们在编程语言中的体现却是基本相同的&#xff0c;但是基本相同并不等…

Java Bullshifier –生成大量随机代码库

生成大量随机Java应用程序的命令行工具 您一直在等待的命令行工具。 或不。 毕竟&#xff0c;这是很深奥的。 无论哪种方式&#xff0c;它对某些人都非常有用&#xff0c;而对其他人来说却是一个有趣的实用程序。 Bullshifier是由David Levanon和Hodaya Gamliel开发的内部Over…

二级c语言光盘,二级c语言(光盘).doc

1程序设计题&#xff1a; 请编写一个函数 unsigned fun (unsigned w ) w是一个大于10的无符号整数。例如&#xff1a;W值为5923&#xff0c;则函数返回923&#xff1b;W值为923&#xff0c;则函数返回23。if ( w >10000 ) w % 10000 ; 程序修改题: m i; 和 if( a[k]>a[m]…

设计模式六大原则(3):依赖倒置原则

定义&#xff1a; 高层模块不应该依赖低层模块&#xff0c;二者都应该依赖其抽象&#xff1b;抽象不应该依赖细节&#xff1b;细节应该依赖抽象。 问题由来&#xff1a;类A直接依赖类B&#xff0c;假如要将类A改为依赖类C&#xff0c;则必须通过修改类A的代码来达成。这种场景下…

Jirasearch 2.0狗粮:使用Lucene查找我们的Jira问题

几年前&#xff0c;我首先构建并发布了Jirasearch &#xff0c;它是用于薄型包装Lucene服务器的有趣的狗粮测试用例&#xff0c;以针对我们的Jira问题公开强大的搜索UI。 这很好地展示了Lucene的许多重要功能&#xff1a; 使用块联接查询来建模父文档&#xff08;原始的Jira问…

Highcharts教程--把js代码从html中抽离出来,放到单独的一个js文件中。由html页面调用...

1.html页面写法 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>第一个 Highcharts 图表</title><!-- 引入 jquery.js --><script src"static/jquery-3.3.1.min.js"><…

数据结构c语言版第16页,数据结构c语言版

数据结构c语言版[编辑]概述《数据结构C语言版》本书的前半部分从抽象数据类型的角度讨论各种基本类型的数据结构及其应用;后半部分主要讨论查找和排序的各种实现方法及综合分析比较出版信息作/译者&#xff1a;严蔚敏&#xff0c;吴伟民 出版社&#xff1a;清华大学出版社出版日…

C语言申请内存时堆栈大小限制

一直都有一个疑问&#xff0c;一个进程可以使用多大的内存空间&#xff0c;swap交换空间以及物理内存的大小&#xff0c;ulimit的stack size对进程的内存使用有怎样的限制&#xff1f;今天特亲自动手实验了一次&#xff0c;总结如下&#xff1a; 开辟一片内存空间有2种方式&…

微服务之数据同步Porter

Porter是一款数据同步中间件&#xff0c;主要用于解决同构/异构数据库之间的表级别数据同步问题。 背景 在微服务架构模式下深刻的影响了应用和数据库之间的关系&#xff0c;不像传统多个服务共享一个数据库&#xff0c;微服务架构下每个服务都要有自己的数据库。如果你想获得微…

C语言采用多文件的工程结构百度,C语言学习知识复习资料结构框架学习知识重点.doc...

C语言学习知识复习资料结构框架学习知识重点.doc .思维导图1C语言程序设计知识结构第一课 C语言程序设计基础思维导图2第一课 C语言程序设计基础本课主要知识点1.知识点C程序基础l C语言是一种结构化程序设计语言。三种基本结构顺序、选择、循环。例1(2010-09-11)以下关于结构化…

antlr_ANTLR –语义谓词

antlr用antlr解析简单的语法很简单 。 您要做的就是使用正则表达式描述您的语言&#xff0c;并让antlr生成词法分析器和解析器。 解析大型或复杂的语言有时会需要更多&#xff0c;因为仅使用正则表达式描述它们是困难的&#xff0c;甚至是不可能的。 语义谓词是在语法内部编写…

栈大小和内存分部问题

今天面试问了一个栈大小问题&#xff0c;问过两次内存的结构问题&#xff0c;都没有答好&#xff0c;这次要弄清楚才行。 栈大小是有默认值的&#xff0c;如果申请的临时变量太大的话就会超过栈大小&#xff0c;造成栈溢出。 编译期限制栈大小&#xff0c;和系统限制栈深度根本…

ssh登陆报错“WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!”的解决方法

解决方法&#xff1a;删除 ~/.ssh/known_hosts转载于:https://www.cnblogs.com/liangxc/p/10414123.html

android 动态修改菜单,如何在Android的“选项”菜单上更改MenuItem?

如何在Android的“选项”菜单上更改MenuItem&#xff1f;我的Activity上有一个选项菜单&#xff0c;带有mymenu.xml“开始”。 选择此3000128611611048489985后&#xff0c;我想更改菜单&#xff0c;使其包含MenuItem“停止”。 最后&#xff0c;当选择“停止”时&#xff0c;我…

Java性能监控:您应该了解的5个开源工具

鲜为人知但有用&#xff1a;开源应用程序性能监视的状态 对于任何应用程序来说&#xff0c;最重要的事情之一就是性能。 我们要确保用户获得他们能获得的最佳体验&#xff0c;并且要知道我们的应用已启动并正在运行。 这就是为什么我们大多数人至少使用一种监视工具的原因。 …

【BZOJ1069】【SCOI2007】—最大土地面积(凸包+旋转卡壳)

传送门 考虑枚举任意222个点&#xff0c;那么只需要枚举第二个点的时候旋转卡壳就可以O(n)O(n)O(n)得到最远点对了 #include<bits/stdc.h> using namespace std; inline int read(){char chgetchar();int res0,f1;while(!isdigit(ch)){if(ch-)f-f;chgetchar();}while(isd…

如何在vs2010中修改栈的大小

上次运行程序的时候提示栈溢出&#xff0c;oh,my god 程序栈空间不够用了&#xff0c;没关系&#xff0c;可以设置栈的大小&#xff0c;默认是1MB。 选择 项目->属性->链接器->系统->堆栈保留大小,然后输入你想要的栈大小即可。

android第三方登录appid,AndroidQQ第三方登录

集成QQ登录在lib导入该open_sdk_r5886_lite.jar包AndroidManifest.xmlandroid:name"com.tencent.tauth.AuthActivity"android:launchMode"singleTask"android:noHistory"true" >android:theme"android:style/Theme.Translucent.NoTitleB…

Java数组、集合的三种遍历方式(包懂)

1 for循环 for(int i 0;i<arr.length;i){System.out.print(arr[i]" "); } 2 foreach循环&#xff0c;这种方式结构简单&#xff0c;可以简化代码 for(int i:arr){System.out.print(arr[i]" "); } 3 迭代器遍历 对于数组而言&#xff0c;就没必要转换为…