【C++】C++ static关键字详解
- static的作用
1.隐藏
当我们编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,其他的源文件也能访问。如,我们有源文件source1.cpp定义了一个全局变量i和函数Func
//source1.cpp
int i = ; void Func()
{
printf("Hello World\n");
}
如果在另一个文件main.cpp中是可以引用i和Func的。然而,如果一个文件要使用在其他源文件定义的变量或函数,一定要在此文件件中包含相应变量或函数的声明。其中变量一定要用extern声明,函数的声明加不加extern没有影响。如下所示:
//source1.cpp
extern int i; //变量i的声明
void Func(); //函数的声明 int main()
{
printf("%d\n", i); //使用变量i
Func(); //使用函数Func() return ;
}
如果加上static前缀,就不能像上面的程序一样被其他程序使用。
static int i = ; static void Func()
{
printf("Hello World\n");
}
2. static的第二个作用是默认初始化为0,包括未初始化的全局变量与局部静态变量。其实,未初始化的全局变量也具备这一属性,因为未初始化的全局变量与未初始化的静态变量时存储在同一块区域内(BSS段)
3. static的第三个作用是保持局部变量内容的持久。
函数内自动变量,当调用时就存在,退出函数时就消失,但静态局部变量虽然在函数内定义,但静态局部变量始终存在着,也就是说它的声明期为整个源程序,其特点是只进行一次初始化且拒具有'记忆性'。
静态局部变量的生存期虽然为为整个源程序,但其作用域仍然与局部变量相同,即只能在定义该变量的函数内使用该变量。退出函数后,尽管该变量还继续存在,但不能继续使用它。
- 类中static的作用
静态数据成员:
C++重用了static这个关键字,并赋予了它与前面不同的含义:表示属于一个类而不是属于此类对象的任何特定对象的变量和函数。我们可以使用作用于操作符和类的对象、引用或指针来访问静态成员。
通常,非static数据成员存在于类类型的每个对象中。不管该类产生多少个对象,静态成员变量永远只有一个实例,而且在没有对象实例的情况下已经存在。不像普通的数据成员,static数据成员独立于该类的任意对象而存在;每个static数据成员是与类关联的对象,并不与该类的对象相关联。也就是说当某个类的实例修改了该静态数据成员变变量,其修改值为该类的其他所有实例所见。
静态数据成员和普通数据成员一样遵从public、protected、private访问规则。
可以通过作用域操作符从类直接调用static成员,或者通过对象、引用或指向该类类型对象的指针间接调用。
类的数据成员也存储在全局(静态)存储区。静态数据成员定义时要分配空间,所以不能在类声明中定义。
static数据成员可以声明为任意类型,可以是常量、引用、数组、类类型,等等。
因为静态数据成员不属于类的任何一个对象,所以它们并不是在创建类的对象时被定义。这意味着它们不是由类的构造函数初始化。而一般来说我们不能在类的内部初始化静态成员(再定义体内初始化会出错)。相反的,必须在类的外部定义和初始化每个静态成员。和其他对象一样,要给静态数据成员只能定义一次。类似于全局变量,静态数据成员定义在任何函数之外。因此一旦被定义,就将一直存在于程序的整个生命周期中。
这个规则的一个例外是,只要初始化是一个常量表达式,整形const static数据成员就可以在类的定义体中进行初始化(不是定义)。然而,const static数据成员必须在类的定义体之外进行定义。只不过定义时,不在需要初始化。
保证对象正好定义一次的最好办法,就是将static数据成员的定义放在包含类的非内联成员函数定义的文件中。
double Account::interestRate = initRate();
像使用任意的类成员一样,在类定义体外部引用类的static成员时,必须指定成员在哪个类中定义的。然而,static关键字只能用于类定义体内部的声明中,定义不能标示为static。
类的静态成员即可以被类的静态方法访问,也可以被非静态方法访问。static成员函数:
静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分,它为类服务而不是为某一个类的具体对象服务。
当在类外部定义静态成员时(不论是变量还是函数),不能重复static关键字,该关键字只出现在类内部声明语句中。
因为普通成员函数总是具体的属于某个类的具体对象,所以普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身。
与普通成员函数相比,静态成员函数由于不与任何的对象相关联,因此它不具有this指针。因而它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数与访问静态数据成员。
因为static成员不是任何对象的组成部分,所以static成员函数不能被声明为const。也不能被声明为虚函数、volatile。
静态成员函数不需要必须经由类对象调用,也可以像静态数据成员一样使用类名、指向类对象的指针或引用调用:class A {
public:
static void Func() {
cout<<"Hello World"<<endl;
} static int i;
}; int A::i = ; int main()
{
A a;
A* pa = &a;
A &ra = a; A::Func(); //使用类型调用静态成员函数
a.Func(); //使用对象调用静态成员函数
pa->Func(); //使用对象指针调用静态成员函数
ra.Func(); //使用对象引用调用静态成员函数 cout<<A::i<<endl; //使用类型调用静态数据成员
cout<<a.i<<endl; //使用对象调用静态数据成员
cout<<pa->i<<endl;//使用对象指针调用静态数据成员
cout<<ra.i<<endl; //使用对象引用调用静态成员数据 return ;
}关于静态成员函数,可以总结为一下几点:
1. 静态成员之间可以相互访问,包括静态成员函数访问静态数据成员以及静态成员函数。静态成员函数不能访问非静态成员函数和非静态数据成员,非静态数据成员可以任意地访问静态成员函数和静态数据成员;2. 由于没有this指针的额外开销,因此静态成员函数与类的非静态程彦函数相比速度上会有些许的增长。
使用静态成员变量而不是全局变量有三个优点:
1)静态成员的名字是在类的作用域,因此可以避免与其他类的成员或全局对象名字冲突2)可以实施封装。static成员可以是私有成员,而全局对象不可以。
3)通过阅读程序容易看出static成员是与特定类关联的。这种可见性可清晰地显示程序员的意图。
- 参考资料
1. 《C++ Primer 第五版》7.6
2. 《王道程序员求职宝典》
3. 《深度探索C++对象模型》
【C++】C++ static关键字详解的更多相关文章
- Java Static关键字详解
提起static关键字,相信大家绝对不会陌生,但是,想要完全说明白,猛的一想,发现自己好像又说不太明白... ...比方说,昨天被一个同学问起的时候... ... 当然,不是所有人都像我一样学艺不精的 ...
- C/C++中static关键字详解
静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0,使用时可以改变其值. 静态变量或静态函数只有本文件内的代码才能访问它,它的名字在其它文件中不可见.用法1:函数内部声明 ...
- C/C++中static关键字详解-zz
静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0,使用时可以改变其值. 静态变量或静态函数只有本文件内的代码才能访问它,它的名字在其它文件中不可见.用法1:函数内部声明 ...
- 【转载】static关键字详解
上一篇博客中,因为一个static关键字没有设置好,导致浪费了大量的时间来寻找程序的错误,归根结底,就是大一的时候c语言没有学好. 现在总算知道了,你现在所学的每一个知识点在不就的以后可能及时你的救命 ...
- Java static 关键字详解
引言 在<Java编程思想>中有这样一段话:static方法就是没有this的方法.在static方法内部不能调用非静态方法,反过来是可以的.而且可以在没有创建任何对象的前提下,仅仅通过类 ...
- Java:final、static关键字 详解+两者结合使用
一 final关键字 1) 关于final的重要知识点 final关键字可以用于成员变量.本地变量.方法以及类. final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误. ...
- java中的static关键字详解
static对于我们这些初学者在编写代码和阅读代码是一个难以理解的关键字,也是大量公司面试题最喜欢考的之一.下面我就来就先讲述一下static关键字的用法和我们初学者容易误解的地方. static关键 ...
- C/C++中的static关键字详解
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用.一.面向过程设计中的sta ...
- static关键字 详解
原文地址:http://blog.csdn.net/keyeagle/article/details/6708077 google了近三页的关于C语言中static的内容,发现可用的信息很少,要么长篇 ...
随机推荐
- SSM-CRUD入门项目——新增与校验
新增 分析: 在Index.jsp页面点击新增,弹出对话框(模态框) 数据库查询部门列表显示在模态框中 用户输入数据完成操作 我们先把模态框构建出来,并对新增按钮添加事件,点击按钮弹出模态框: < ...
- 20155212 2016-2017-2 《Java程序设计》第4周学习总结
20155212 2016-2017-2 <Java程序设计>第4周学习总结 教材学习内容总结 Chapter 6 继承基本上就是避免多个类间重复定义共同行为. private成员会被继承 ...
- mysql常用的命令
一.事件操作: (1)查看事件启动状态 show variables like 'event_scheduler'; select @@event_scheduler; (2)启动事件 set glo ...
- Ceph学习之路(二)之Ceph的工作原理及流程
一.RADOS的对象寻址 Ceph 存储集群从 Ceph 客户端接收数据——不管是来自 Ceph 块设备. Ceph 对象存储. Ceph 文件系统.还是基于 librados 的自定义实现——并存储 ...
- 海思NB-IOT的SDK里面写KV键值对值掉电保存参数
1. 写函数,ICCID_CTRL_KEY 这个是键,有些是海思已经使用的,所以自己定义的时候要错开,函数的第二个参数是数据指针,第三个参数是数据长度 #define ICCID_CTRL_KEY ...
- AndroidStudio 新建不同的Drawable文件夹
以前习惯eclipse开发Android的朋友们知道 新创建一个Android项目的时候eclipse会自动生成多个drawable文件夹来存放图片 但是Android Studio 新建项目的时候只 ...
- 一、初识 Django
一.引子 Django最初设计用于具有快速开发需求的新闻类站点,目的是要实现简单快捷的网站开发! 从好的方面来看,Web 开发激动人心且富于创造性:从另一面来看,它却是份繁琐而令人生厌的工作.通过减少 ...
- Sublime Text 3高效实用快捷键
2017-11-27 16:18:48 Sublime Text 3 高效实用快捷键 Sublime Text 3 软件及注册码 官网下载链接在这里,有时候会很神奇的上不去,可能是因为被Q了,可能就是 ...
- centos7.2下解决用Mysql 使用navicate远程连接数据库出现1045 access denied for user 'root'@'localhost' using password yes
在mysql命令行中执行 SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456'); GRANT ALL PRIVILEGES ON *.* ...
- 如何使用HtmlTestRunner让自动化测试报告内容更丰富
原文出自:http://www.cnblogs.com/tsbc/p/4128150.html 简述 使用selenium webdriver + Python做自动化测试,执行完成后要生成测试报告, ...