C/C++中的static
一、静态全局变量
理解static关键字之前首先回顾一下C/C++程序的在内存中的分配情况。从低地址到高地址依次分为:代码区、全局数据区、堆区、栈区。函数之外的全局变量和静态变量(包括全局变量和静态变量)都存储在全局数据区,堆区有程序员自己通过malloc,new申请内存,栈区存放函数内部的临时变量,随着函数的退出而释放内存。
静态全局变量和普通全局变量的区别:
- 静态全局变量和普通全局变量都存储在全局变量区,在这一点两者是相同的。
- 普通全局变量的作用域是整个工程,在某个文件中定义的全局变量,被其它文件引用时,在开头处用extern标明使用的外部变量即可。而静态全局变量的作用域是定义该变量的文件,无法在外部文件引用。
例如:当n是全局变量是可以正常通过的,当n定义为静态全局变量是无法编译通过的
//Example2
//File1第一个代码文件的代码
#include<iostream>
#include "example2.h"
int n; //定义静态全局变量
void main()
{
n=;
std::cout<<n<<std::endl; //
fn(); //
}
//File2第二个代码文件的代码
#include<iostream.h>
extern int n;
void fn()
{
n++;
std::cout << n << endl;
}
二、静态局部变量
我们知道定义在函数内部的局部变量存放在栈区,随着程序退出函数,系统会回收栈内存,局部变量会失效。有些时候需要通过引入静态局部变量,将局部变量存放在全局数据区。静态局部变脸只在第一次初始化,每次的值保存到下一次调用,始终驻留在全局数据区,直到程序退出。静态全局变量的作用域没有改变,依然是局部的。
#include<iostream>
using namespace std;
void fn();
void main()
{
fn();
fn();
fn();
}
void fn()
{
static int n=;
cout << n << endl;
n++;
}
三、静态函数
关于静态函数限制函数作用域的做法,我C++试验了一下,发现已经不起作用了。另一方面确实很少使用,就不多讲了。C++面向对象中,比较关键的是静态成员、静态成员函数。
四、静态成员变量
- 对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类型的所有对象共享访问,包括其派生类的对象。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新;
- 静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以必须在类中申明,类外定义。例如在在下面的例子中,int Myclass::Sum=0;是定义静态数据成员;
- 静态数据成员和普通数据成员一样遵从public,protected,private访问规则;如果静态数据成员定义访问权限允许的话,定义为public;可以通过<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>访问公有静态成员
- 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性;
- 可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能;
#include<iostream>
using namespace std;
class Myclass {
public:
Myclass(int a, int b, int c);
static void GetSum(); //声明静态成员函数
private:
int a, b, c;
static int Sum; //声明静态数据成员 };
int Myclass::Sum = ; //定义并初始化静态数据成员 Myclass::Myclass(int a, int b, int c) {
this->a = a;
this->b = b;
this->c = c;
Sum += a + b + c; //非静态成员函数可以访问静态数据成员
}
void Myclass::GetSum() { //静态成员函数实现
//cout << a << endl; // error,a是非静态成员
cout << "Sum=" << Sum << endl;
}
int main() {
cout << sizeof(Myclass) << endl; //静态成员不占用对象空间
Myclass M(, , );
M.GetSum();
Myclass::GetSum(); //静态成员函数访问
Myclass N(, , );
N.GetSum();
M.GetSum();
return ;
}
五、静态成员函数
- 和静态成员变量一样,也可以定义静态成员函数。静态成员函数为类的所有对象服务,不是为类的某个具体对象服务
- 静态成员函数在类中声明,在类中类外事项都可以,在类外实现时,不能加static关键字。静态成员必须在类中声明,类外初始化
- 静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;非静态成员函数可以任意地访问静态成员函数和静态数据成员;静态成员函数不能访问非静态成员函数和非静态数据成员;
- 由于静态成员函数没有this指针,因此无法访问非静态成员和非静态成员函数
- 静态成员函数的访问可以使用类的访问方式<类名::成员函数>或者对象成员的访问方式<对象.成员函数>、<对象指针->成员函数>
- 静态成员函数不可以同时声明为 virtual、const、volatile函数
C/C++中的static的更多相关文章
- Android 中关于static的使用问题
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5251564.html 项目中,在不停地接收串口数据很长一段时间(几小时)后,会偶然性的报错.初步排除了oom ...
- (转)Java中的static关键字解析
转载: http://www.cnblogs.com/dolphin0520/p/3799052.html 一.static关键字的用途 在<Java编程思想>P86页有这样一段话: &q ...
- 关于Java中的static关键字
Java中的 static 关键字,确实是一个关键的字(key word),今天就来总结一下它的用法,说说为什么关键. Java中的 static 关键字主要是用来做内存管理的.理解了这句话才能够比较 ...
- Java中的static关键字解析
Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...
- C++中的static关键字的总结
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. 1.面向过程设计中的st ...
- java中的static使用--静态变量、静态方法
Java 中的 static 使用之静态变量 大家都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立.然而在某些时候,我们更希望该类所有的对象共享同一个成员.此时就是 s ...
- (转)Java中的static关键字解析
转自http://www.cnblogs.com/dolphin0520/p/3799052.html 一.static关键字的用途 在<Java编程思想>P86页有这样一段话: “sta ...
- Java中的static的使用
Java中的static使用之静态变量 神话丿小王子的博客主页 1.Java 中被static修饰的成员称为静态成员或类成员.它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享.且优先于对象 ...
- java中的static详解
如果一个类成员被声明为static,它就能够在类的任何对象创建之前被访问,而不必引用任何对象.static 成员的最常见的例子是main( ) .因为在程序开始执行时必须调用main() ,所以它被声 ...
- Java 中的 static 使用之静态变量
大家都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立.然而在某些时候,我们更希望该类所有的对象共享同一个成员.此时就是 static 大显身手的时候了!! Java 中 ...
随机推荐
- hdu 5038 求出现次数最多的grade
http://acm.hdu.edu.cn/showproblem.php?pid=5038 模拟水题 求出现次数最多的grade.如果有多个grade出现的次数一样多,且还有其他的grade,则把这 ...
- springmvc elf8848
刚开始觉得孔浩讲得好,之后觉得开涛讲得好,现在觉得elf8848讲得好.其实只是自己学习的各个阶段 孔浩:环境搭建,做了个基础的CRUD 开涛:讲了Controller(不该看),注解,数据绑定,请求 ...
- LeetCode135:Candy
题目: There are N children standing in a line. Each child is assigned a rating value. You are giving c ...
- PYQT5实现 关闭 提示弹框
当关闭窗口时,要实现如下功能: def closeEvent(self, event): reply = QtWidgets.QMessageBox.question(self, '警告', '退出后 ...
- 前台ajax请求一次,后台代码执行了两次
问题: 后台使用Django,前台发布文章时使用ajax方式,后台执行代码将data数据取出存入数据库 经过排查,是提交按钮type写成了submit,需要写成button,真是 修改后测试 代码执行 ...
- ASP.NET开发常用简单实用的方法
ASP.NET开发简单实用的方法 一.打印和导出 打印和导出EXCEL在目前ASP.NET开发中可以说是必要的,有时候针对不同数据难易程度下,用有效快速的方法是解决办法的有效途径之一. 1.打印 后台 ...
- 我所理解的网络游戏<?>:战斗逻辑设计
客户端发送消息,统一在服务器端触发战斗 服务器端驱动战斗过程 客户端端接收用户输入向服务器发送消息 客户端接收服务器消息显示客户端表现 1. 服务器--客户端交互(战斗流程) 整战斗流程分为4个状 ...
- 四两拨千斤式的攻击!如何应对Memcache服务器漏洞所带来的DDoS攻击?
本文由 网易云发布. 近日,媒体曝光Memcache服务器一个漏洞,犯罪分子可利用Memcache服务器通过非常少的计算资源发动超大规模的DDoS攻击.该漏洞是Memcache开发人员对UDP协议支 ...
- [USACO06DEC] 牛奶模式Milk Patterns
题目链接:戳我 我们知道后缀数组的h数组记录的是后缀i和后缀i-1的最长公共前缀长度,后缀的前缀其实就是子串. 因为是可以重复出现的子串,所以我们只要计算哪些h数组的长度大于等于x即可.这一步操作我们 ...
- SPOJ Longest Common Substring II
题目连接:戳我 题目大意:求n个字符串的最长公共子串. 它的简化版--这里 当然我们可以用SA写qwq,也可以用广义SAM写qwq 这里介绍纯SAM的写法...就是对其中一个建立后缀自动机,然后剩下的 ...