static关键字有俩作用:(1).控制存储分配;(2).控制一个名字的可见性和连接。
 
随着C++名字空间的引入,我们有了更好的,更灵活的方法来控制一个大项目的名字增长。
 
 
在类的内部使用static是在全程序中控制名字的另一种方法。这些名字不会与全局名冲突,并且可见性和访问也限制在程序内部,使得在维护代码时有更多的控制。

数据成员可以分静态变量、非静态变量两种.
  静态成员:静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于内存,所以非静态成员可以直接访问类中静态的成员.

  非成静态员:所有没有加Static的成员都是非静态成员,当类被实例化之后,可以通过实例化的类名进行访问。非静态成员的生存期决定于该类的生存期..而静态成员则不存在生存期的概念,因为静态成员始终驻留在内容中。

一个类中也可以包含静态成员和非静态成员,类中也包括静态构造函数和非静态构造函数。

在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。
静态成员的定义或声明要加个关键static。静态成员可以通过双冒号来使用即<类名>::<静态成员名>

class Point
{
public:
void init()
{
}
static void output()
{
}
};
int main(void)
{
Point::init();
Point::output();
}

  

编译出错:error C2352: 'Point::init' : illegal call of non-static member function
结论1:不能通过类名来调用类的非静态成员函数。

通过类的对象调用静态成员函数和非静态成员函数

int main(void)
{
Point pt;
pt.init();
pt.output();
} 

编译通过。
结论2:类的对象可以使用静态成员函数和非静态成员函数。

在类的静态成员函数中使用类的非静态成员#include <stdio.h>  class Point

{
public:
void init()
{
}
static void output()
{
printf("%d\n", m_x);
}
private:
int m_x;
}; int main()
{
Point pt;
pt.output();
}

  

在类的静态成员函数中使用类的非静态成员
编译出错:error C2597: illegal reference to data member 'Point::m_x' in a static member function
因为静态成员函数属于整个类,在类实例化对象之前就已经分配空间了,而类的非静态成员必须在类实例化对象后才有内存空间,所以这个调用就出错了,就好比没有声明一个变量却提前使用它一样。
结论3:静态成员函数中不能引用非静态成员。

在类的非静态成员函数中使用类的静态成员: 

class Point
{
public:
void init()
{
output();
}
static void output()
{
}
};
int main()
{
Point pt;
pt.output();
return 0;
}

编译通过。
结论4:类的非静态成员函数可以调用用静态成员函数,但反之不能。

使用类的静态成员变量:

#include <stdio.h>
class Point
{
public:
Point()
{
m_nPointCount++;
}
~Point()
{
m_nPointCount--;
}
static void output()
{
printf("%d\n", m_nPointCount);
}
private:
static int m_nPointCount;
};
int main()
{
Point pt;
pt.output();
return 0;
}

编译无错误,生成EXE程序时报链接错误。

error LNK2001: unresolved external symbol "private: static int Point::m_nPointCount" (?m_nPointCount@Point@@0HA)
这是因为类的静态成员变量在使用前必须先初始化。
在main()函数前加上int Point::m_nPointCount = 0;
再编译链接无错误,运行程序将输出1。
结论5:类的静态成员变量必须先初始化再使用。

结合上面的五个例子,对类的静态成员变量和成员函数作个总结:
一. 静态成员函数中不能调用非静态成员。
二. 非静态成员函数中可以调用静态成员。因为静态成员属于类本身,在类的对象产生之前就已经存在了,所以在非静态成员函数中是可以调用静态成员的。
三. 静态成员变量使用前必须先初始化(如int MyClass::m_nNumber = 0;),否则会在linker时出错。

  

最新文章

  1. .net core快速上手
  2. shelve模块
  3. AFN网络状态的时时监控以及网络的判断、
  4. 使用JDK开发Servlet程序
  5. 网站添加到IIS和附件进程调试(新手使用篇)
  6. mysql---索引及explain的作用
  7. Swift入门系列--Swift官方文档(2.2)--中文翻译--About Swift 关于Swift
  8. Node.js权威指南 (11) - 加密与压缩
  9. Y - Design T-Shirt(第二季水)
  10. WPF笔记(1.9 样式和控件模板)——Hello,WPF!
  11. 【编码问题】if,for语句与中文编码
  12. 2017 Multi-University Training Contest - Team 1 1011&amp;&amp;HDU 6043 KazaQ&#39;s Socks【规律题,数学,水】
  13. Python创建容器和集合之源码分析
  14. python 3.7 安装mysqlclient 错误解决
  15. 基于MFC开发的指纹识别系统.
  16. 算法(第四版)C# 习题题解——2.1
  17. OS + Windows 10 / office excel vlookup / CredSSP
  18. flex 布局压缩问题
  19. android--Activity有返回值的跳转
  20. 快速搭建一个“微视”类短视频 App

热门文章

  1. 通过运行窗口输入命令方式,打开Internet窗口
  2. spring bean.xml
  3. str_pad()函数
  4. 搭建python-flask开发环境
  5. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_02 泛型_5_定义和使用含有泛型的接口
  6. Python Error: “ImportError: No module named six”,用自动安装解决依赖问题
  7. POI向Excel中写入数据及追加数据
  8. 小程序-web-view嵌入H5页面遇到的bug
  9. mysql5.7密码登录的那些坑
  10. Spring Boot系列(三) Spring Boot 之 JDBC