static也是我们经常用到的关键字,关于static有很多用法,而且在面向过程和面向对象编程中,static有着不同的意义。之前总是记不住,于是,本人强迫症又发作了,一定要搞懂它!!!
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string> using namespace std; static int s_test; int nons_test; int _tmain(int argc, _TCHAR* argv[]) { //静态全局变量默认初始化为0 cout<<"static :"<<s_test<<endl; //非静态全局变量默认初始化也是0,但如果是局部非静态变量,在VS中直接报错,不能通过编译 cout<<"non-static: "<<nons_test<<endl; system("pause"); return 0; }
//StaticTest.h头文件中分别定义静态全局变量和普通全局变量 static int static_num = 20; int nonstatic_num = 30;
// C++Test.cpp : 定义控制台应用程序的入口点。 //全局变量在头文件或者本文件中两者没有什么区别 #include "stdafx.h" #include <iostream> #include <string> #include "StaticTest.h" #include "StaticTest1.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { //如果静态变量在头文件中或者本文件中,可以访问静态全局变量 cout<<"static :"<<static_num<<endl; //如果静态变量在头文件中或者本文件中,可以访问非静态全局变量 cout<<"non-static: "<<nonstatic_num<<endl; system("pause"); return 0; }
//.h文件 #ifndef __STATICTEST1_H_ #define __STATICTEST1_H_ #pragma once class StaticTest1 { public: StaticTest1(void); virtual ~StaticTest1(void); }; #endif //.cpp文件 #include "stdafx.h" #include "StaticTest1.h" //在.cpp文件中定义全局变量 static int static_test = 10; int nonstatic_test = 20; StaticTest1::StaticTest1(void) { } StaticTest1::~StaticTest1(void) { }
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include "StaticTest1.h" using namespace std; extern int nonstatic_test; extern int static_test; int _tmain(int argc, _TCHAR* argv[]) { //如果静态变量在其他.cpp文件中,不可以访问静态全局变量,即使在本文件使用extern声明也不行 //cout<<"static :"<<static_test<<endl; //如果静态变量在其他.cpp文件中,可以访问非静态全局变量,但是要在本文件使用extern声明 cout<<"non-static: "<<nonstatic_test<<endl; system("pause"); return 0; }
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string> #include <vector> using namespace std; void TestFunc() { //定义一个静态局部变量,但是这个变量仅仅在第一次的时候初始化,再次调用时不会再初始化 static int static_num = 10; //但是普通局部变量,每次都会初始化 int nonstatic_num = 10; static_num++; nonstatic_num++; cout<<"non_static: "<<nonstatic_num<<" static :"<<static_num<<endl; } int _tmain(int argc, _TCHAR* argv[]) { //调用10次该函数 for(int i = 0; i < 10; i++) TestFunc(); system("pause"); return 0; }
结果:
non_static: 11 static :11
non_static: 11 static :12
non_static: 11 static :13
non_static: 11 static :14
non_static: 11 static :15
non_static: 11 static :16
non_static: 11 static :17
non_static: 11 static :18
non_static: 11 static :19
non_static: 11 static :20
请按任意键继续. . .
从上面的结果我们看出,函数被调用了10次,非静态变量每次都被初始化,因而结果没变。而静态变量却只被初始化了一次,因而每次结果都比上一次大1。
关于局部静态变量要注意的几点:
1)局部静态变量也在全局数据区分配内存,不会因为函数调用结束而销毁。
2)局部静态变量在首次调用到该变量的时候进行初始化,之后再次调用时不会再进行初始化。并且局部静态变量一般就在声明处初始化,如果未显示初始化,则默认初始化为0
3)局部静态变量的生命周期为声明时到程序结束,但是它的作用域却是局部的,仅仅在该函数内,不会破坏局部性原理。
//StaticTest.h #include <iostream> using namespace std; void NormalFuncTest(); static void StaticFuncTest();
//StaticTest.cpp #include "stdafx.h" #include "StaticTest.h" void NormalFuncTest() { cout<<"Normal Func!"<<endl; } static void StaticFuncTest() { cout<<"Static Func!"<<endl; }
// C++Test.cpp : 定义控制台应用程序的入口点。 //main函数 #include "stdafx.h" #include <iostream> #include "StaticTest.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { NormalFuncTest(); StaticFuncTest(); system("pause"); return 0; }这个例子中有两个函数,都定义在另一个文件中,一个为普通函数,另一个为static函数。编译一下,会出现如下错误:
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> using namespace std; class StaticTest { private: //此处为声明,声明一个静态成员变量 static int count; int id; public: StaticTest(int i): id(i) { count++; } void Show() { cout<<"ID: "<<id<<endl; } static void ShowCount() { cout<<"Count: "<<count<<endl; } }; //在类外定义并初始化静态成员变量,由于定义时需要分配空间,所以不能在类声明中定义 int StaticTest::count = 0; int _tmain(int argc, _TCHAR* argv[]) { StaticTest test1(1); StaticTest test2(2); test1.Show(); test2.Show(); StaticTest::ShowCount(); system("pause"); return 0; }
还是上面的那个例子,加了一部分功能:
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> using namespace std; class StaticTest { private: //此处为声明,声明一个静态成员变量 static int count; int id; public: StaticTest(int i): id(i) { count++; } void Show() { //但是非静态成员函数可以访问静态成员函数和变量 cout<<"ID: "<<id<<" Count: "<<count<<endl; } static void ShowCount() { //静态成员函数不能访问非静态的成员,非静态成员函数也不行! //cout<<"ID: "<<id<<endl; error C2597: 对非静态成员“StaticTest::id”的非法引用 //Show();: error C2352: “StaticTest::Show”: 非静态成员函数的非法调用 cout<<"Count: "<<count<<endl; } }; //在类外定义并初始化静态成员变量,由于定义时需要分配空间,所以不能在类声明中定义 int StaticTest::count = 0; int _tmain(int argc, _TCHAR* argv[]) { StaticTest test1(1); StaticTest test2(2); test1.Show(); test2.Show(); StaticTest::ShowCount(); system("pause"); return 0; }
结果:
ID: 1 Count: 2
ID: 2 Count: 2
Count: 2
请按任意键继续. . .
关于静态成员函数注意的地方:
1)静态成员函数可以访问静态成员函数和静态成员变量。但是静态成员函数不能访问普通成员变量和普通成员函数。(因为静态成员函数没有this指针,属于共用)
2)非静态成员函数可以访问静态成员变量和静态成员函数。
3)定义在类外的静态成员函数不能加static,声明时加个static即可,定义时和普通成员函数相同。
4)静态成员函数与静态成员变量的调用规则一致,都不需要有对象就能调用。可以使用正常方法,也可以使用类名::调用。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/puppet_master/article/details/47347695