概述
static主要有三种使用方式,其中前两种在C/C++中使用,第三种只在C++语言中使用
1)静态局部变量 2)静态全局变量/函数 3)静态成员变量/函数3 静态成员变量/函数
3.1静态成员变量
静态成员是C++所特有的,在类内数据成员的声明前加上关键字static,该数据成员就是类的静态数据成员了。
class CGame{public: CGame(); virtual ~CGame(); void drawGameArea(); void drawGameInfo(); void changeInfo(); void run(); bool checkFailed(); bool checkLevel();public: static const int KLEFT; static const int KUP; static const int KWIDTH; static const int KHEIGHT; static const int KSCORE_OFFSET; static const int KLEVEL_OFFSET;private: CFood *m_pFood; CSnake *m_pSnake; int m_iScore; //游戏得分 int m_iLevel; //关卡设置};
以上的代码中
static const int KLEFT; static const int KUP; static const int KWIDTH; static const int KHEIGHT; static const int KSCORE_OFFSET; static const int KLEVEL_OFFSET;
就是类的静态成员。
static成员变量的特点:- 静态数据成员和普通数据成员一样遵从public,privateed,protected访问规则
- 静态数据成员初始化的格式为:
<数据类型> <类名> :: <静态数据成员名> = <值>值> 静态数据成员名> 类名> 数据类型>
实例如下:
//静态成员变量的初始化const int CGame::KLEFT = 5;const int CGame::KUP = 2;const int CGame::KWIDTH = 70;const int CGame::KHEIGHT = 20;const int CGame::KSCORE_OFFSET = 50;const int CGame::KLEVEL_OFFSET = 65;
无论类的对象被定义了多少个,静态数据成员在程序中只有一份拷贝,由该类型的所有对象共享访问。
类中定义了静态成员变量,一定要记得初始化! 参考: 《C++使用静态类成员时出现的一个问题》3.2静态成员函数
静态成员函数同静态成员变量一样,它为类服务而不是为类的具体对象服务。一般普通成员函数都隐含一个this指针,this指针指向类的对象本身,而静态成员函数不存在this指针,因为静态成员函数不属于任何对象,它属于类。静态成员函数无法访问类对象的非静态成员(包括非静态数据成员和非静态成员函数)。 可以采用下述格式进行静态成员函数的调用
<类名> :: <静态成员函数名> ( <参数表> ) 参数表> 静态成员函数名> 类名>
小心陷阱
1 静态成员函数可以访问静态成员,但绝不能访问非静态成员。2 静态成员不能声明为虚函数。这是因为静态成员函数在对象实例未生成前便可以调用。而如果对象实例未产生,虚函数调用使用的虚函数表未生成,导致虚函数调用时不知调用子类的虚函数还是父类的虚函数 【实际的应用】 在俄罗斯方块项目中,为了绘制方便,需要改变光标的位置,因此需要实现一个函数void gotoxy(int x,int y)
在C++的体系中,不希望把gotoxy()作为一个游离的全局函数,所以用一个类来单独的实现这个函数,同时又希望这个函数可以随时随地的使用,就把它编写为一个类的静态成员函数。如果真的声明成一个类的函数,每次用的时候,都要实例化一个对象,这样就太麻烦了。
gotoxy()函数的实现#include "CCommFunc.h"#includevoid CCommFunc::gotoxy(int x, int y){ COORD cd; cd.X = x; cd.Y = y; //SetConsoleCursorPosition()函数用来设置控制台光标位置 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cd); }
该函数的使用
/*******************************************Description: 绘制主窗体程序Input: int needLayers 当前通关所需要的层数 int currentLayers 当前已经消去的层数Ouput: 无Return: 无Others: 无*********************************************/void CInfoBoard::drawInfoBoard(int needLayers, int currentLayers){ if (needLayers < currentLayers) { return; } CCommFunc::gotoxy(this->m_offsetX,this->m_offsetY); cout << "------------------------"; CCommFunc::gotoxy(this->m_offsetX,this->m_offsetY + 1); cout << " NEED: " << needLayers << " "; CCommFunc::gotoxy(this->m_offsetX, this->m_offsetY + 2); cout << " NOW: " << currentLayers << " "; CCommFunc::gotoxy(this->m_offsetX, this->m_offsetY + 3); cout << "-------------------------";}