博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【编码的法则】谨慎的使用static
阅读量:6786 次
发布时间:2019-06-26

本文共 2865 字,大约阅读时间需要 9 分钟。

概述

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"#include
void 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 << "-------------------------";}

转载于:https://www.cnblogs.com/Manual-Linux/p/11017751.html

你可能感兴趣的文章
Kalman原理(很详细)本文转载自《学习OpenCV》清华大学出版社 于诗琪 刘瑞祯 译...
查看>>
linux/centos6 系统时间同步 同步系统时间 ntpdate
查看>>
第一次开启51CTO博客
查看>>
升职还需犹豫?
查看>>
我的友情链接
查看>>
CMD框变小字体显示乱码
查看>>
正则总结:JavaScript中的正则表达式
查看>>
HAProxy 详解
查看>>
7.1文件查找之find命令详解
查看>>
Linux系统管理-(11)-网络配置ifcfg家族
查看>>
memset()
查看>>
Jquery Ajax二次封装(部分转载)
查看>>
android studio3 logcat无日志的问题
查看>>
我的友情链接
查看>>
tinyxml使用
查看>>
mariadb
查看>>
iOS 时间与日期处理
查看>>
Linux中yum网络服务器与本地服务器的安装
查看>>
[2013.12.28更新:构建教程,支持CB2、CT] 构建自己的Debian Linux
查看>>
flume+kafka+storm运行实例
查看>>