4.8 静态成员
2016-06-13 08:51
232 查看
由关键字static修饰说明的类成员,成为静态类成员(static
class member),包括:静态数据成员和静态函数成员。类的静态成员为其所有对象共享,不管有多少对象,静态成员只有一份存于公用内存中。
虽然使用static修饰说明,但与函数中的静态变量有明显差异。
在类定义中,用关键字static修饰的数据成员为静态数据成员。该类产生的所有对象共享系统为静态成员分配的一个存储空间,而这个存储空间是在编译时分配的,在定义对象时不再为静态成员分配空间。静态数据实际上是该类所有对象所共有的,它更像在面向过程程序设计时的全局变量,可提供同一类的所有对象之间信息交换的捷径。
正因为静态数据成员不属于类的某一特定对象,而是属于整个类的,所以使用时可用以下格式:
类名::静态数据成员名
【例4.9】用静态数据成员计算由同一类建立的对象的数量。
#include <iostream.h>
class Ctest
{
private:
static int count;//注意私有
public:
Ctest()
{
++count;
cout<<"对象数量="<<count<<'\n';
}
~Ctest()
{
--count;
cout<<"对象数量="<<count<<'\n';
}
};
int Ctest::count=0; //A行 对静态数据成员的定义性说明 void main(void)
{
Ctest a[3];
}
执行程序后输出:
对象数量=1 //a[0]构造函数产生
对象数量=2 //a[1]构造函数产生
对象数量=3 //a[2]构造函数产生
对象数量=2 //a[2]析构函数产生
对象数量=1 //a[1]析构函数产生
对象数量=0 //a[0]析构函数产生
此例中A行是对静态成员数据数据作定义性说明,必须在文件作用域中作一次并只能做一次说明,只有在这时C++编译器为静态数据成员分配存储空间。C++静态数据成员缺省的初值为0,所以A行中“=0”是可以省去的。
特别要注意不管静态变量是私有或公有,定义性说明均有效。
◆ 1、函数成员说明为静态,将与该类的不同对象无关。严格地讲,在逻辑上该函数成员只有一个拷贝。
静态函数成员的调用,在对象之外可以采用下面的方式: 类名::函数名
与静态数据成员相反,为使用方便,静态函数成员多为公有的。
【例4.8_2】与静态数据成员相反,为使用方便,静态函数成员多为公有的。在例4.8中的复数类中的函数成员print(),如被说明为静态的则可如下表达:
static void print()
{
cout<<”Real=”<<Real<<’\t’<<”Image=”<<Image<<’\n’;
}
因它是独立于具体对象而存在的,似乎可以用complex::print(
)来调用。但是因为数据不确定(C++系统不知应取哪一个对象的数据)而不能运行。
在本例中print()函数应改为:
static void print(complex & ob)
{
cout<<”Real=”<<ob.Real<<’\t’<<”Image=”<<ob.Image<<’\n’ ;
}
这里用complex的对象的引用为参数,而以具体的complex对象为实参,这样就能正常运行了。
◆ 2、如果静态成员函数在类定义之外定义时,则不能在定义时再加static,这一点与友元函数类似。因为static不属于数据类型组成部分。
因为C++在产生类的对象时,为了减少对象所占空间,物理上将同一类的所有对象的成员函数只保留一个拷贝,所以一般情况下定义静态函数不能取得明显好处,只有逻辑上的优点。反而在使用上变得不方便,通常是没有必要去定义静态成员函数的。
class member),包括:静态数据成员和静态函数成员。类的静态成员为其所有对象共享,不管有多少对象,静态成员只有一份存于公用内存中。
虽然使用static修饰说明,但与函数中的静态变量有明显差异。
静态数据成员
在类定义中,用关键字static修饰的数据成员为静态数据成员。该类产生的所有对象共享系统为静态成员分配的一个存储空间,而这个存储空间是在编译时分配的,在定义对象时不再为静态成员分配空间。静态数据实际上是该类所有对象所共有的,它更像在面向过程程序设计时的全局变量,可提供同一类的所有对象之间信息交换的捷径。正因为静态数据成员不属于类的某一特定对象,而是属于整个类的,所以使用时可用以下格式:
类名::静态数据成员名
【例4.9】用静态数据成员计算由同一类建立的对象的数量。
#include <iostream.h>
class Ctest
{
private:
static int count;//注意私有
public:
Ctest()
{
++count;
cout<<"对象数量="<<count<<'\n';
}
~Ctest()
{
--count;
cout<<"对象数量="<<count<<'\n';
}
};
int Ctest::count=0; //A行 对静态数据成员的定义性说明 void main(void)
{
Ctest a[3];
}
执行程序后输出:
对象数量=1 //a[0]构造函数产生
对象数量=2 //a[1]构造函数产生
对象数量=3 //a[2]构造函数产生
对象数量=2 //a[2]析构函数产生
对象数量=1 //a[1]析构函数产生
对象数量=0 //a[0]析构函数产生
此例中A行是对静态成员数据数据作定义性说明,必须在文件作用域中作一次并只能做一次说明,只有在这时C++编译器为静态数据成员分配存储空间。C++静态数据成员缺省的初值为0,所以A行中“=0”是可以省去的。
特别要注意不管静态变量是私有或公有,定义性说明均有效。
静态函数成员
◆ 1、函数成员说明为静态,将与该类的不同对象无关。严格地讲,在逻辑上该函数成员只有一个拷贝。静态函数成员的调用,在对象之外可以采用下面的方式: 类名::函数名
与静态数据成员相反,为使用方便,静态函数成员多为公有的。
【例4.8_2】与静态数据成员相反,为使用方便,静态函数成员多为公有的。在例4.8中的复数类中的函数成员print(),如被说明为静态的则可如下表达:
static void print()
{
cout<<”Real=”<<Real<<’\t’<<”Image=”<<Image<<’\n’;
}
因它是独立于具体对象而存在的,似乎可以用complex::print(
)来调用。但是因为数据不确定(C++系统不知应取哪一个对象的数据)而不能运行。
在本例中print()函数应改为:
static void print(complex & ob)
{
cout<<”Real=”<<ob.Real<<’\t’<<”Image=”<<ob.Image<<’\n’ ;
}
这里用complex的对象的引用为参数,而以具体的complex对象为实参,这样就能正常运行了。
◆ 2、如果静态成员函数在类定义之外定义时,则不能在定义时再加static,这一点与友元函数类似。因为static不属于数据类型组成部分。
因为C++在产生类的对象时,为了减少对象所占空间,物理上将同一类的所有对象的成员函数只保留一个拷贝,所以一般情况下定义静态函数不能取得明显好处,只有逻辑上的优点。反而在使用上变得不方便,通常是没有必要去定义静态成员函数的。
相关文章推荐
- Morris遍历二叉树
- Debian Jessie Sources
- android相对布局详解
- 4.7 友元
- 爱尔兰B计算器的MFC实现
- webView
- yii 主从数据库分离-转载http://www.yiichina.com/doc/guide/2.0/db-dao
- java PDF转WORD 只适合纯文本
- 学习WCF之路6:会话
- 4.6 运算符重载
- Java开发中的23种设计模式详解(转)
- generate
- 4.5 引用与复制构造函数
- Ubuntu16.04 系统错误报告屏蔽
- 第十六周实践项目之阅读程序————6
- 高煥堂的VR產業見解
- Android权限系统
- 常用正则表达式,持续更新中。。。
- Java 接口使用,工具类的分析
- eclipse 编码