【编码的法则】谨慎的使用static
概述
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的更多相关文章
- .Net(c#)汉字和Unicode编码互相转换
{"Tilte": "\u535a\u5ba2\u56ed", "Href": "http://www.cnblogs.com&q ...
- 中文字符串转换为十六进制Unicode编码字符串
package my.unicode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Uni ...
- java-base64编码和解码
一.反射/*** * encode by Base64 */ public static String encodeBase64(byte[]input) throws Exception{ Clas ...
- Java生成BASE64编码
1.所需jar包: BASE64Encoder.jar 2.在导包过程中,可能会出现工程不识别的情况.即:不能找到BASE64Encoder的jar包.此时,可以有两种方法解决这个问题: a. 只需 ...
- C# Unicode编码
为了避免在浏览器中传输数据的时候出现中文乱码,我们可以将内容进行URL编码,当然也可以将内容进行UNICODE编码.将汉字进行UNICODE编码,如:"王"编码后就成了" ...
- Bencode的编码与解码
开源地址: https://github.com/CreateChen/Bencode Nuget: Install-Package Bencode 1. Bencode规则 BEncoding是Bi ...
- Java安全编码之用户输入
0x00 安全引言 1.传统Web应用与新兴移动应用 (1)传统Web应用:浏览器 HTTP 服务器(2)新兴移动应用:APP HTTP 服务器 从安全角度看,传统Web应用与新兴移动应用没有本质区别 ...
- 普通字符串与Hex编码字符串之间转换
import java.io.UnsupportedEncodingException; import org.apache.commons.codec.binary.Hex; public clas ...
- 【C#基础】实现URL Unicode编码,编码、解码相关整理
1.Unicode编码 引用系统 System.Web using System.Web; string postdata = "SAMLRequest=" + HttpUtili ...
随机推荐
- SpringBoot项目的前端+thymeleaf模板引擎
SpringBoot项目创建之后,后台的框架是SpringMVC.但前端的resource和template目录都是空的.这个时候需要创建前台页面. 习惯上,我们会创建JSP,但是,SpringBoo ...
- 13-1 jquery操作cookie
jQuery之cookie操作 Cookies 定义:让网站服务器把少量数据存储到客户端的硬盘或内存,从客户端的硬盘里读取数据的一种技术; 下载与引入:jquery.cookie.js基于jquery ...
- [django]上下文管理器
上下文管理器django提取context中的数据去供模板调用 需求: 所有的页面都需要一个特定的变量 本质: python函数 , 接收一个HttpRequest对象的参数 , 且返回的必须是一个字 ...
- Oracle Flashback Transaction Query with Oracle Flashback Version Query
Oracle Flashback Transaction Query with Oracle Flashback Version Query In this example, a database a ...
- shell脚本一一项目5
主题:一键查看占用内存.cpu高的进程 echo "----------------cpu top 10 list----------------"ps -eo pid,pcpu, ...
- 必须Mark!43个优秀的Swift开源项目推荐(转)
作为一门集百家之长的新语言,Swift拥有着苹果先天的生态优势,而其在GitHub上各种优秀的开源项目也层出不穷.本文作者@SwiftLanguage从2014年6月苹果发布Swift语言以来,便通过 ...
- appium xpath元素定位
1.id定位 写法:driver.find_element_by_id("这里是resource-id") 2.name定位 name定位就是通过UI Automator工具查看的 ...
- Python 爬取淘宝商品数据挖掘分析实战
Python 爬取淘宝商品数据挖掘分析实战 项目内容 本案例选择>> 商品类目:沙发: 数量:共100页 4400个商品: 筛选条件:天猫.销量从高到低.价格500元以上. 爬取淘宝商品 ...
- MySQL 编码:utf8 与 utf8mb4,utf8mb4_unicode_ci 与 utf8mb4_general_ci
参考:mysql字符集小结 utf8mb4 已成为 MySQL 8.0 的默认字符集,在MySQL 8.0.1及更高版本中将 utf8mb4_0900_ai_ci 作为默认排序规则. 新项目只考虑 u ...
- TensorFlow学习笔记9-深度模型的优化
深度模型的优化 回顾概念: 代价函数时训练集上损失函数的平均: \[J(\theta)=E_{(x,y)\sim \hat{p}_{data}}L(f(x;\theta),y) \tag{1}\] 引 ...