转:C语言中的static变量和C++静态数据成员(static member)
转自:C语言中的static变量和C++静态数据成员(static member)
C语言中static的变量:
1).static局部变量
a、静态局部变量在函数内定义,生存期为整个程序运行期间,但作用域与自动变量相同,只能在定义该变量的函数内使用。退出该函数后, 尽管该变量还继续存在,但不能使用它。
b、对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。
2).static全局变量
全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。但是他们的作用域,非静态全局变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件(.h或.cpp)内有效, 在同一源程序的其它源文件中不能使用它(注意,这一点和C++是不同的)。
关于C语言static变量的理解:
A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C、静态变量和全局变量放在程序的全局数据区,而不是在堆栈中分配,所以不可能导致堆栈溢出;
D、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题(线程不安全);
C++中静态数据成员的特点有::
1、静态数据成员仅仅在初始化时不受访问权限的约束;
2、静态数据成员最好不要在.h文件中进行定义(初始化),而是放在.cpp文件中定义(初始化);
3、静态数据成员被类的所有对象所共享,包括类的派生类的所有对象;——即派生类和基类共享一个静态成员。
4、静态数据成员的类型可是所属类自己,即在一个类中可以声明该类自己的类型的静态成员对象,但是,不可以定义普通的成员对象,(指针可以)
5、在const成员函数中,可以修改static成员变量的值。普通成员变量的值,是不能修改的。
6、static成员函数只能访问static成员,不能访问非static成员,并且static成员函数不能定义为virtual、const、volatile 函数。
详细分析如下:
类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。
和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。注意::仅仅是初始化时不遵守public/protected/private的规则。
即:如果是private和protected的静态成员,只能通过public的静态成员函数进行调用,而不能通过类名直接访问了。
1、静态数据成员的定义(初始化)不能在头文件中。
静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)不应该被放在头文件中。
其定义方式与全局变量相同。举例如下:
xxx.h文件
class base
{
private:
static const int _i; //声明,标准c++支持有序类型在类体中初始化,但vc6不支持。
};
xxx.cpp文件
const int base::_i=10; //仅仅在定义(初始化)时不受private和protected访问限制.
注:不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的错误。即使加上#ifndef #define #endif或者#pragma once也不行。
2、静态数据成员 被 类 的所有对象所共享,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员。举例如下:
class base
{
public :
static int _num; //声明
};
int base::_num=0; //静态数据成员的真正定义
class derived:public base
{
};
main()
{
base a;
derived b;
a._num++;
cout<<"base class static data number _num is"<<a._num<<endl;
b._num++;
cout<<"derived class static data number _num is"<<b._num<<endl;
}
// 结果为1,2;可见派生类与基类共用一个静态数据成员。
3、静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为所属类类型的 指针或引用。举例如下:
class base{
public :
static base _object1; //正确,静态数据成员
base _object2; //错误
base *pObject; //正确,指针
base &mObject; //正确,引用 (引用需要在构造函数的参数初始化列表中初始化,如下:)
};
这个类要能创建对象,需要定义带有参数初始化列表的构造函数,如下:
class base{
public :
static base _object1; //正确,静态数据成员
base *pObject; //正确,指针
base &mObject; //正确,引用
base():mObject(*this){}
};
4、静态数据成员的值在const成员函数中可以被合法的改变,而不破那个数据成员的值,不能在const成员函数中改变。
#include <iostream>
using namespace std;
class Student
{
private:
static int a;
int b;
public:
void change() const;
void setB(int b);
int getB();
static int getA();
};
void Student::change() const
{
a++; //这个可以,因为a是static成员变量。
b++; //不可以,因为b是普通成员变量(如果b不是成员变量(是全局变量,普通参数,函数内部定义的临时变量)也可以别修改),且是const函数
}
int Student::getA()
{
return a;
}
void Student::setB(int b)
{
this->b = b;
}
int Student::getB()
{
return b;
}
int Student::a = 5;
int main(int argc,char *argv[])
{
Student stu;
stu.setB(10);
stu.change();
cout<<Student::getA()<<endl;
cout<<stu.getB()<<endl;
return 0;
}
即:成员函数的const约束,只起作用于类的普通成员变量,对于全局变量,成员函数参数,成员函数内部的临时变量起不到作用。
转:C语言中的static变量和C++静态数据成员(static member)的更多相关文章
- C++中static修饰的静态成员函数、静态数据成员
1.静态成员函数.静态数据成员 在类中,用static修饰的成员函数被称为静态成员函数,而用static修饰的数据成员就称为静态数据成员:与普通的成员函数和数据成员不同, 静态成员函数和静态数据成员有 ...
- 静态数据成员(面向对象的static关键字)
静态数据成员: 在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员.先举一个静态数据成员的例子. #include<iostream> using namesp ...
- 内部类不能有静态变量(除静态的对Static的理解)
关于内部类(static与final) Static 不用实例化就能加载进内存 而内部类需要外部类实例化后才能加载进内存.这就间接造成static需要实例化了.与static不需要实例化语义矛盾 1. ...
- Java语言中的volatile变量
Java中的两种内置同步机制: synchronized 和 volatile 变量, volatile修饰的变量, 在使用时会强制检查最新值. 有synchronized的值可见性, 但是没有其操作 ...
- 在不同语言中static的用法
static (计算机高级语言) 编辑 像在VB,C#,C,C++,Java,PHP中我们可以看到static作为关键字和函数出现,在其他的高级计算机语言如FORTRAN.ALGOL.COBOL.BA ...
- (转)static 变量
一. static 变量 static变量大致分为三种用法1. 用于局部变量中,成为静态局部变量. 静态局部变量有两个用法,记忆功能和全局生存期.2. 用于全局变量,主要作用是限制此全局变量被其他的文 ...
- 为什么static数据成员一定要在类外初始化?(转)
1.避免重复定义和初始化 <<c++ primer>>说在类外定义和初始化是保证static成员变量只被定义一次的好方法. 但,为什么static const int就可以在类 ...
- 再看static数据成员
当将类的某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享.各个对象都拥有类中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少类对象无关. ...
- C语言中static变量详解
Static翻译出来是“静态”“静止”的意思,在C语言中的意思其实和它的本意差不多,表示“静态”或者“全局”的意思,用来修饰变量和函数.经static修饰过后的变量或者函数的作用域或者存储域会发生变化 ...
随机推荐
- ASP.NET生成缩略图的代码
01. // <summary> 02. /// 生成缩略图 03. /// </summary> 04. /// &l ...
- volatile关键字解析
转载:http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受 ...
- [Python] 使用有道翻译API
Python 使用youdao (有道翻译)API 想写一个给自己记录背单词状况的软件,需要获取英文单词的中文释义(基本功能).考虑使用有道翻译的API实现获取英文单词的中文释义的方法. 获取API_ ...
- 2016-2017 CT S03E05: Codeforces Trainings Season 3 Episode 5 (2016 Stanford Local Programming Contest, Extended) B
链接:http://codeforces.com/gym/101116 学弟做的,以后再补 #include <iostream> #include <stdio.h> #in ...
- 2016年11月20日 星期日 --出埃及记 Exodus 20:11
2016年11月20日 星期日 --出埃及记 Exodus 20:11 For in six days the LORD made the heavens and the earth, the sea ...
- JAVA中线程池启动定时任务
/** * 用线程池启动定时器 * @param args */ public static void main(String[] args) { //10秒启动 Executors.newSched ...
- MSM8909平台 LED背光的控制
之前齐师兄问我,是不是应该有一个文件记录背光灯的亮度,我说理论上有,但是在哪里我真的还没有见过.只知道在调LCD驱动的时候会调用一个背光控制的函数,传进来一个亮度值就可以配置亮度了,至于这个函数是谁调 ...
- Update与FixedUpdate区别
以下的代码能使游戏暂停,记得要使速度*Time.deltaTime,目的是保证游戏运行在帧数不同的情况下,角色移动速度都一样,因为此时角色是按时间移动与帧数无关. using UnityEngine; ...
- 图片格式转换之ImageMagick
项目中需要实现一些图片文件到TIFF文件的转换,去网上下载了一些第三方软件. 好的软件需要收费,免费的存在各种问题. 自己动手,丰衣足食! 众里寻他千百度,蓦然回首,那人就是ImageMagick. ...
- Java——Socket编程(一)
1. 网络基础知识 两台机器之间需要进行通信,需要满足的条件: 每个机器有一个唯一的标识符(IP地址): 他们之间进行通信需要用同一种语言(协议): 每台主机上面有多个应用程序,如QQ,微博,迅雷等, ...