静态成员变量和静态成员函数(static)
数据成员可以分静态变量、非静态变量两种.
静态成员:静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于内存,所以非静态成员可以直接访问类中静态的成员.
非成静态员:所有没有加Static的成员都是非静态成员,当类被实例化之后,可以通过实例化的类名进行访问..非静态成员的生存期决定于该类的生存期..而静态成员则不存在生存期的概念,因为静态成员始终驻留在内容中..
一个类中也可以包含静态成员和非静态成员,类中也包括静态构造函数和非静态构造函数..
分两个方面来总结,第一方面主要是相对于面向过程而言,即在这方面不涉及到类,第二方面相对于面向对象而言,主要说明static在类中的作用。
一、在面向过程设计中的static关键字
1、静态全局变量
定义:在全局变量前,加上关键字 static 该变量就被定义成为了一个静态全局变量。
特点:
A、该变量在全局数据区分配内存。
B、初始化:如果不显式初始化,那么将被隐式初始化为0(自动变量是随机的,除非显式地初始化)。
C、访变量只在本源文件可见,严格的讲应该为定义之处开始到本文件结束。
例(摘于C++程序设计教程---钱能主编P103): //file1.cpp
//Example 1
#include <iostream.h>
void fn();
static int n; //定义静态全局变量
void main()
{
n=20;
cout<<n<<endl;
fn();
}
void fn()
{
n++;
cout<<n<<endl;
}
D、文件作用域下声明的const的常量默认为static存储类型。
静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分布情况如下图:
代码区全局数据区堆区栈区
一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。细心的读者可能会发现,Example 1中的代码中将
static int n; //定义静态全局变量
改为:
int n; //定义全局变量
程序照样正常运行。的确,定义全局变量就可以实现变量在文件中的共享,但定义静态全局变量还有以下好处:
静态全局变量不能被其它文件所用;(好像是区别extern的) 其它文件中可以定义相同名字的变量,不会发生冲突; 您可以将上述示例代码改为如下: //Example 2//File1#include <iostream.h>void fn();static int n; //定义静态全局变量(只能在本文件中使用)void main(){ n=20; cout<<n<<endl; fn();}//File2#include <iostream.h>extern int n;(可在别的文件中引用这个变量)void fn(){ n++; cout<<n<<endl;}
编译并运行Example 2,您就会发现上述代码可以分别通过编译,但link时出现错误。试着将 static int n; //定义静态全局变量
改为int n; //定义全局变量
再次编译运行程序,细心体会全局变量和静态全局变量的区别。
2、静态局部变量
定义:在局部变量前加上static关键字时,就定义了静态局部变量。
我们先举一个静态局部变量的例子,如下:
//Example 3#include <iostream.h>void fn();void main(){ fn(); fn(); fn();}void fn(){ static n=10; cout<<n<<endl; n++;}
通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。
但有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。
静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。
特点:
A、该变量在全局数据区分配内存。
B、初始化:如果不显式初始化,那么将被隐式初始化为0,以后的函数调用不再进行初始化。
C、它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或 语句块结束时,其作用域随之结束。
3、静态函数(注意与类的静态成员函数区别)
定义:在函数的返回类型前加上static关键字,函数即被定义成静态函数。
特点:
A、静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。
静态函数的例子:
//Example 4#include <iostream.h>static void fn();//声明静态函数void main(){ fn();}void fn()//定义静态函数{ int n=10; cout<<n<<endl;}
定义静态函数的好处:
静态函数不能被其它文件所用; 其它文件中可以定义相同名字的函数,不会发生冲突; 二、面向对象的static关键字(类中的static关键字) 1、静态数据成员
在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。先举一个静态数据成员的例子。
//Example 5
#include <iostream.h>
class Myclass{
public: Myclass(int a,int b,int c);
void GetSum();
private: int a,b,c;
static int Sum;//声明静态数据成员
};
int Myclass::Sum=0;//定义并初始化静态数据成员
Myclass::Myclass(int a,int b,int c)
{
this->a=a;
this->b=b;
this->c=c;
Sum+=a+b+c;
}
void Myclass::GetSum(){
cout<<"SSum="<<Sum<<endl;
}
void main()
{
Myclass M(1,2,3);
M.GetSum();
Myclass N(4,5,6);
N.GetSum();
Myclass::GetSum();
}
关于静态成员函数,可以总结为以下几点:
出现在类体外的函数定义不能指定关键字static; 静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数; 非静态成员函数可以任意地访问静态成员函数和静态数据成员; 静态成员函数不能访问非静态成员函数和非静态数据成员; 由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长; 调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式: <类名>::<静态成员函数名>(<参数表>)
调用类的静态成员函数。
静态成员变量和静态成员函数(static)的更多相关文章
- c++学习笔记之类和对象(三、static静态成员变量和静态成员函数)
一.static静态成员变量 对象的内存中包含了成员变量,不同的对象占用不同的内存,这使得不同对象的成员变量相互独立,它们的值不受其他对象的影响.是有时候我们希望在多个对象之间共享数据,对象 a 改变 ...
- static作用,静态成员变量和静态成员函数
static关键字有俩作用:(1).控制存储分配:(2).控制一个名字的可见性和连接. 随着C++名字空间的引入,我们有了更好的,更灵活的方法来控制一个大项目的名字增长. 在类的内部使用s ...
- C++类中的静态成员变量与静态成员函数
最近一直看c++相关的项目,但总是会被c++类中的静态成员变量与静态成员函数的理解感觉很是模糊,不明白为什么类中要是用静态成员变量.于是在网上搜集了一些资料,自己再稍微总结下. 静态成员的概念: 静态 ...
- 13.C++-静态成员变量、静态成员函数
首先回顾下成员变量 能通过对象名能够访问public成员变量 每个对象的成员变量都是专属的 成员变量不能在对象之间共享 再来讲讲类的静态成员变量 介绍 静态成员变量属于整个类所有 静态成员变量的生命期 ...
- C++解析(14):静态成员变量与静态成员函数
0.目录 1.静态成员变量 2.静态成员函数 3.小结 1.静态成员变量 成员变量的回顾: 通过对象名能够访问public成员变量 每个对象的成员变量都是专属的 成员变量不能在对象之间共享 新的需求: ...
- C++ 类中的静态成员变量,静态成员函数
//类中的静态成员变量,静态成员函数 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; /* ...
- Java中非静态成员变量、静态成员变量的初始化时机
转: Java中非静态成员变量.静态成员变量的初始化时机. 2018年05月22日 11:48:11 SilenceCarrot 阅读数 421 版权声明:技术就要分享才有意思,欢迎大家分享(注明 ...
- C++学习10 static静态成员变量和静态成员函数
一般情况下,如果有N个同类的对象,那么每一个对象都分别有自己的成员变量,不同对象的成员变量各自有值,互不相干.但是有时我们希望有某一个或几个成员变量为所有对象共有,这样可以实现数据共享. 可以使用全局 ...
- static 关键字 静态成员变量及静态成员函数
static类成员 类成员类似于C语言的全局变量,但是与全局变量又有所不同,例如,全局变量是可以被任何的用户代码所修改,而且全局变量破坏了对象的封装性. 使用类的 static 成员的优点 使用 st ...
随机推荐
- android 常用adb 及linux 命令
一.ADB相关 adb shell:进入连接的USB调试模式设备shell命令行下 adb tcpip 5555:将USB连接的调试及的连接方式改为网络远程模式进行调试 这里端口为5555(adb 默 ...
- [翻译] JFMinimalNotifications
JFMinimalNotifications This is an iOS UIView for presenting a beautiful notification that is highly ...
- [翻译] CotEditor
CotEditor https://github.com/coteditor/CotEditor CotEditor is a lightweight plain-text editor for OS ...
- web开发方面会遇到哪些缓存?分别如何优化
Web缓存定义: Web缓存游走于服务器和客户端之间,这个服务器可能是源服务器(资源所驻留的服务器Add),数量可能是1个或多个. Web缓存就在服务器-客户端之间搞监控,监控请求,并且把请求输出的内 ...
- SQL server数据库的部署
一.实验目标 1.安装一台SQL SERVER(第一台),然后克隆再一台(第二台),一共两台,修改两台的主机和IP地址. 2.使用注册的方式,用第二台远程连接第一台 二.实验步骤 1)先打开一台Wi ...
- mac lnmp
Mac下安装LNMP(Nginx+PHP5.6)环境 Mac下安装LNMP(Nginx+PHP5.6)环境 安装Homebrew 最近工作环境切换到Mac,所以以OS X Yosemite(10.10 ...
- 【转】.net core 一次坑爹的类库打包过程
自己遇到这个问题,记录一下,原文链接:http://www.cnblogs.com/Hai--D/p/5776463.html. 众所周知,.net core 跨平台类库引用一定要通过nuget获得. ...
- HBase学习之路 (八)HBase大牛博客
主要是记录一下链接 http://hbasefly.com
- CUDA和OpenGL互操作经典博文赏析和学习
1.使用cuda+opengl图形互操作性实现MPR.原学位论文学习:实时交互的医学图像可视化.在该论文的第5.1.1节. 2.cuda与opengl互操作之PBO 3.cuda与opengl互操作之 ...
- 1349: Taking Pebbles (博弈 打表找规律)
1349: Taking Pebbles Submit Page Summary Time Limit: 1 Sec Memory Limit: 128 Mb Submit ...