C++中关键字的理解--Static
C++中关键字的理解---Static
目录:1、static缘起
2、static自我理解
3、static举例使用
4、总结
--------------------------------------------------------------------------------------------------
1、static缘起
C语言是面向过程构架,多文件为单位的编码的优异之处在于保持不同源文件和函数之间的相互引用(即联系)和相互独立,因而产生了extern和static关键字。而面向过程的C和面向对象的C++有千丝万缕的联系,暂且不说用C可以完全构架和模拟衍化出C++,第二部分用我自己的理解会用一句话来描述:关键字static同C++的牵连。除此之外,需要知道:既然关键字Static修饰的是变量/函数,那么这些数据都放在哪?
---进程在内存中的布局:
上图中的文本段保持的是程序的二进制数据;.data段保存进程所有已初始化的全局变量;.bss(Block Started by Symbol)段保存程序中未被初始化的全局变量的一块内存区域,该段属于静态内存分配。进程的生命周期中,.data段和.bss段内数据同整个进程步伐一致。
2、static自我理解
static类似于C++中私有保护,专属性由于深海鱼和水的关系,离开深海既死(程序出错)。
C++private私有保护(只在类内活动,可通过成员函数调用,类外使用不行);
static静态全局变量(只在定义它的源文件--c/cpp,中有效,其他源文件无法访问);
有人形象的形容普通全局变量穿上static外衣后,它就变成了新娘,已心有所属,只能被定义它的源文件(新郎)中的变量或函数访问。
3、static举例使用
1>全局静态变量
file1.h:声明子代码
#include<stdio.h> void printStr(); void printS();
file1.cpp定义一个静态的全局变量hello,仅可以在file1.cpp下的函数printStr和printS访问
#include"file1.h" static char* hello = "hello cobing!"; void printStr(){ printf("%s\n", hello); } void printS(){ printf("%s\n", hello); printf("%s\n", hello); }
file2.cpp引用file1.h声明下和调用file1.cpp下的定义函数,来对比是否能在不同源文件下来对静态全局变量访问
#include"file1.h" void printfileStr(){ printf("%s\n", hello); }
结果证明是不行的。
main.cpp主文件中的main函数通过调用file1下的函数可以访问静态全局变量,这和C++中private无异
#include"file1.h" int main(){ printStr(); printS(); return 0; }
上面几个函数证明了静态全局变量的私有保护性比较👍!
2>局部静态变量
局部静态变量 VS 普通局部变量
1】 位置: 静态局部变量被编译器放在全局存储区.data,所以它虽然是局部的,但是在程序的整个生命周期中存在。
2】 访问权限:静态局部变量只能被其作用域内的变量或函数访问。也就是说虽然它会在程序的整个生命周期中存在,由于它是static的,它不能被其他的函数和源文件访问。
3】 值:静态局部变量如果没有被用户初始化,则会被编译器自动赋值为0,以后每次调用静态局部变量的时候都用上次调用后的值。这个比较好理解,每次函数调用静态局部变量的时候都修改它然后离开,下次读的时候从全局存储区读出的静态局部变量就是上次修改后的值。
-------一句话,静态局部变量的私有保护强度进一步(╯▔皿▔)╯升级,在静态全局基础上限制为:只能在同源文件下的同函数内。
eg:
file1.h用上面的即可。
/*static 局部*/ void printStr(){ int normal = 0; static int stat = 0;//静态局部变量 printf("normal = %d ---- stat = %d\n", normal, stat); normal++; stat++; }
上面直接应用是有错的,证明的是私有性更强了。
上面结果证明:静态局部变量的时候都用上次调用后的值(好像记忆断电,每次在原来基础上作用)。但普通的局部变量一直是初始化的状态为0;
3>静态函数
参考链接:http://blog.csdn.net/keyeagle/article/details/6708077/ 作者写的已经非常(๑•̀ㅂ•́)و✧棒了!
4》补充 类中定义的static 成员变量 是属于 全局静态变量的 -----在类内只是一个声明而已
#pragma once class CLearnStatic_Test { public: CLearnStatic_Test(); ~CLearnStatic_Test(); // 类内普通成员变量 int m_nTest;//定义 int m_nTest2; static int m_nStatic;// 声明 静态成员变量,但是前有static关键词, //不属于类内,只是名义上属于类,但其实是属于全局变量 //在这只是声明而已,没有真实的内存空间 };
#include "LearnStatic_Test.h" int CLearnStatic_Test::m_nStatic;//m_nStatic类内声明,需要类外定义;否则也会报错,if只声明 CLearnStatic_Test::CLearnStatic_Test() { m_nTest = m_nTest2 = 0;//在自构函数中对类内成员变量进行初始化 } CLearnStatic_Test::~CLearnStatic_Test() { }
#include "LearnStatic_Test.h" #include<iostream> using namespace std; int main(){ CLearnStatic_Test T1, T2;//m_nTest;和m_nTest2;这两个变量必须与对象(即实例化)关联 CLearnStatic_Test::m_nStatic = 33;//调用公开的静态成员变量(),不需要同对象相关联(即实例化); //直接调用就行,但属于 cout << "sizeof(T1) = " << sizeof(T1) << endl;//类实例化T1的大小值,成员函数肯定没有大小此时; cout << "sizeof(T2) = " << sizeof(T2) << endl;//该句为了证明Static后的变量只是声明而已,并没有占内存空间 cout << "sizeof(m_nStatic) = " << sizeof(CLearnStatic_Test::m_nStatic) << endl;//反而Static后的m_nStatic然后定义的是全局静态变量 return 0; }
实例化对象后,看其大小sizeof(),只是各个成员变量的大小总和,并不包含static 定义的成员变量的大小---因为其属于全局
对类中定义的Static 成员变量初始化可以如下 :
假如类class CStudent{ static int m_nStatic;};
static int m_nStatic;(类内声明)
class CLearnStatic_Test { public:// 类内普通成员变量 int m_nTest;//定义 int m_nTest2; static int m_nStatic;// 声明 静态成员变量,但是前有static关键词, //不属于类内,只是名义上属于类,但其实是属于全局变量 //在这只是声明而已,没有真实的内存空间 };
类的对象T1(实例化后),在局部变量中也没有包含m_nStatic
4、总结
一句话,Static生在C 类似C++中private;