概述

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;
  • 无论类的对象被定义了多少个,静态数据成员在程序中只有一份拷贝,由该类型的所有对象共享访问。

    类中定义了静态成员变量,一定要记得初始化!

    参考:https://www.cnblogs.com/Manual-Linux/p/10996457.html 《C++使用静态类成员时出现的一个问题》

3.2静态成员函数

静态成员函数同静态成员变量一样,它为类服务而不是为类的具体对象服务。一般普通成员函数都隐含一个this指针,this指针指向类的对象本身,而静态成员函数不存在this指针,因为静态成员函数不属于任何对象,它属于类。静态成员函数无法访问类对象的非静态成员(包括非静态数据成员和非静态成员函数)。

可以采用下述格式进行静态成员函数的调用

<类名>::<静态成员函数名>(<参数表>)

小心陷阱

1 静态成员函数可以访问静态成员,但绝不能访问非静态成员。

2 静态成员不能声明为虚函数。这是因为静态成员函数在对象实例未生成前便可以调用。而如果对象实例未产生,虚函数调用使用的虚函数表未生成,导致虚函数调用时不知调用子类的虚函数还是父类的虚函数

【实际的应用】

在俄罗斯方块项目中,为了绘制方便,需要改变光标的位置,因此需要实现一个函数

void gotoxy(int x,int y)

在C++的体系中,不希望把gotoxy()作为一个游离的全局函数,所以用一个类来单独的实现这个函数,同时又希望这个函数可以随时随地的使用,就把它编写为一个类的静态成员函数。如果真的声明成一个类的函数,每次用的时候,都要实例化一个对象,这样就太麻烦了。

gotoxy()函数的实现

#include "CCommFunc.h"
#include<Windows.h> 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 << "-------------------------";
}
  • 2019-7-16 更新:静态成员函数没有this指针

今天在写代码的时候,Create()函数在类中的声明如下所示

static IController* Create(IControllerFactory* f);

在实现Create()函数时候,不自觉的使用了this,导致编译器报错

IController* IController::Create(IControllerFactory* f)
{
if(!f)
{
return nullptr;
}
this->m_f = f;
IController* c = f->CreateC();
// c->m_f = f;
c->m = f->CreateM();
c->v = f->CreateV(); return c;
}

提示错误为:

error: C2355: “this”: 只能在非静态成员函数或非静态数据成员初始值设定项的内部引用

【编码的法则】谨慎的使用static的更多相关文章

  1. .Net(c#)汉字和Unicode编码互相转换

    {"Tilte": "\u535a\u5ba2\u56ed", "Href": "http://www.cnblogs.com&q ...

  2. 中文字符串转换为十六进制Unicode编码字符串

    package my.unicode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Uni ...

  3. java-base64编码和解码

    一.反射/*** * encode by Base64 */ public static String encodeBase64(byte[]input) throws Exception{ Clas ...

  4. Java生成BASE64编码

    1.所需jar包: BASE64Encoder.jar 2.在导包过程中,可能会出现工程不识别的情况.即:不能找到BASE64Encoder的jar包.此时,可以有两种方法解决这个问题: a.  只需 ...

  5. C# Unicode编码

    为了避免在浏览器中传输数据的时候出现中文乱码,我们可以将内容进行URL编码,当然也可以将内容进行UNICODE编码.将汉字进行UNICODE编码,如:"王"编码后就成了" ...

  6. Bencode的编码与解码

    开源地址: https://github.com/CreateChen/Bencode Nuget: Install-Package Bencode 1. Bencode规则 BEncoding是Bi ...

  7. Java安全编码之用户输入

    0x00 安全引言 1.传统Web应用与新兴移动应用 (1)传统Web应用:浏览器 HTTP 服务器(2)新兴移动应用:APP HTTP 服务器 从安全角度看,传统Web应用与新兴移动应用没有本质区别 ...

  8. 普通字符串与Hex编码字符串之间转换

    import java.io.UnsupportedEncodingException; import org.apache.commons.codec.binary.Hex; public clas ...

  9. 【C#基础】实现URL Unicode编码,编码、解码相关整理

    1.Unicode编码 引用系统 System.Web using System.Web; string postdata = "SAMLRequest=" + HttpUtili ...

随机推荐

  1. wnmp部署

    原文地址:   https://www.cnblogs.com/chaooo/p/5462781.html Before:提前规划好的目录结构 1.安装Nginx 到Nginx官网下载最新稳定版 ht ...

  2. [CSP-S模拟测试]:e(树上主席树)

    题目传送门(内部题66) 输入格式 第一行,一个正整数$n$,一个自然数$q$,一个整数$type$.第二行,$n$个正整数,代表$a_i$.接下来$n-1$行,每行两个正整数$u$.$v$,代表树中 ...

  3. angular ajax

    在使用angular 发送ajax的时候,状态信息是正常的,状态码200,返回的参数是使用@responsebody转换后返回的字串.在前端却总是在调用错误的回调函数,也拿不到正确的反馈信息. 回调函 ...

  4. NSIS打包后无法解压7z资源包的问题

    以前产品一直都是好好的.今天突然不行了.找了半天原因,原来发现7Z的压缩属性变成了"LZMA2"了. 要LZMA才行.

  5. ubuntu命令整理中

    系统变量文件: ~/.bashrc 打印系统变量:echo $ANDROID_NDK 查看磁盘空间:df -h 解压缩: .tar.gz 解压:tar zxvf FileName.tar.gz 压缩: ...

  6. cenos 7 中firewalld开放服务端口

    转载 CentOS 7 为firewalld添加开放端口及相关资料   1.运行.停止.禁用firewalld 启动:# systemctl start  firewalld 查看状态:# syste ...

  7. 第三方框架:EventBus

    1 研发背景 案例:我们在主页点收藏按钮,未登录状态,跳登录界面,在登录界面跳注册页面,注册成功,关闭注册页面,关闭登录页面,回到主页,刷新item列表和登录状态. 我们一般会用到发送广播和接收广播来 ...

  8. javascript 动态修改css样式方法汇总(四种方法)

    在很多情况下,都需要对网页上元素的样式进行动态的修改.在JavaScript中提供几种方式动态的修改样式,下面将介绍方法的使用.效果.以及缺陷. 1.使用obj.className来修改样式表的类名. ...

  9. 查询SQL Server数据库所有表字段备注

    SELECT 表名 = case when a.colorder=1 then d.name else '' end, 表说明 = case when a.colorder=1 then isnull ...

  10. 模块内高内聚?模块间低耦合?MVC+EF演示给你看!

    前言 在软件项目开发过程中,我们总能听见“高内聚,低耦合”,即使这种思想在我们学习编程的过程中就已经耳濡目染.可一旦当我们上项目,赶进度的时候我们就会“偷懒”,能省时间就省.管他什么设计模式,什么软件 ...