C++静态数据成员与静态成员函数
一般情况下,如果有n个同类的对象,那么每一个对象都分别有自己的数据成员,不同对象的数据成员各自有值,互不相干。但是有时人们希望有某一个或几个数据成员为所有对象所共有,这样可以实现数据共享。
可以使用全局变量来达到共享数据的目的。例如在一个程序文件中有多个函数,每一个函数都可以改变全局变量的值,全局变量的值为各函数共享。但是用全局变量的安全性得不到保证,由于在各处都可以自由地修改全局变量的值,很有可能偶然失误,全局变量的值就被修改,导致程序的失败。因此在实际工作中很少使用全局变量。
如果想在同类的多个对象之间实现数据共享,也不要用全局对象,可以用静态的数据成员。
静态数据成员
静态数据成员是一种特殊的数据成员。它以关键字static开头。例如
- class Box
- {
- public :
- int volume( );
- private :
- static int height; //把height定义为静态的数据成员
- int width;
- int length;
- };
如果希望各对象中的height的值是一样的,就可以把它定义为静态数据成员,这样它就为各对象所共有,而不只属于某个对象的成员,所有对象都可以引用它。
静态的数据成员在内存中只占一份空间。每个对象都可以引用这个静态数据成员。静态数据成员的值对所有对象都是一样的。如果改变它的值,则在各对象中这个数据成员的值都同时改变了。这样可以节约空间,提高效率。
关于静态数据成员的几点说明:
1) 如果只声明了类而未定义对象,则类的一般数据成员是不占内存空间的,只有在定义对象时,才为对象的数据成员分配空间。但是静态数据成员不属于某一个对象,在为对象所分配的空间中不包括静态数据成员所占的空间。静态数据成员是在所有对象之外单独开辟空间。只要在类中定义了静态数据成员,即使不定义对象,也为静态数据成员分配空间,它可以被引用。
在一个类中可以有一个或多个静态数据成员,所有的对象共享这些静态数据成员,都可以引用它。
2) 对于静态变量,如果在一个函数中定义了静态变量,在函数结束时该静态变量并不释放,仍然存在并保留其值。静态数据成员也类似,它不随对象的建立而分配空间,也不随对象的撤销而释放(一般数据成员是在对象建立时分配空间,在对象撤销时释放)。静态数据成员是在程序编译时被分配空间的,到程序结束时才释放空间。
3) 静态数据成员可以初始化,但只能在类体外进行初始化。如
int Box::height=10; //表示对Box类中的数据成员初始化
其一般形式为:
数据类型类名::静态数据成员名=初值;
不必在初始化语句中加static。
注意,不能用参数对静态数据成员初始化。如在定义Box类中这样定义构造函数是错误的:
Box(int h,int w,int len):height(h){ } //错误,height是静态数据成员
如果未对静态数据成员赋初值,则编译系统会自动赋予初值0。
4) 静态数据成员既可以通过对象名引用,也可以通过类名来引用。请观察下面的程序。
[例9.10] 引用静态数据成员。
- #include <iostream>
- using namespace std;
- class Box
- {
- public:
- Box(int,int);
- int volume( );
- static int height; //把height定义为公用的静态的数据成员
- int width;
- int length;
- };
- Box::Box(int w,int len) //通过构造函数对width和length赋初值
- {
- width=w;
- length=len;
- }
- int Box::volume( )
- {
- return(height*width*length);
- }
- int Box::height=10; //对静态数据成员height初始化
- int main( )
- {
- Box a(15,20),b(20,30);
- cout<<a.height<<endl; //通过对象名a引用静态数据成员
- cout<<b.height<<endl; //通过对象名b引用静态数据成员
- cout<<Box::height<<endl; //通过类名引用静态数据成员
- cout<<a.volume( )<<endl; //调用volume函数,计算体积,输出结果
- }
上面3个输出语句的输出结果相同(都是10)。这就验证了所有对象的静态数据成员实际上是同一个数据成员。
请注意,在上面的程序中将height定义为公用的静态数据成员,所以在类外可以直接引用。可以看到在类外可以通过对象名引用公用的静态数据成员,也可以通过类名引用静态数据成员。即使没有定义类对象,也可以通过类名引用静态数据成员。这说明静态数据成员并不是属于对象的,而是属于类的,但类的对象可以引用它。如果静态数据成员被定义为私有的,则不能在类外直接引用,而必须通过公用的成员函数引用。
5) 有了静态数据成员,各对象之间的数据有了沟通的渠道,实现数据共享,因此可以不使用全局变量。全局变量破坏了封装的原则,不符合面向对象程序的要求。但是也要注意公用静态数据成员与全局变量的不同,静态数据成员的作用域只限于定义该类的作用域内(如果是在一个函数中定义类,那么其中静态数据成员的作用域就是此函数内)。在此作用域内,可以通过类名和域运算符“::”引用静态数据成员,而不论类对象是否存在。
C++静态数据成员与静态成员函数的更多相关文章
- C++学习5-面向对象编程基础(构造函数、转换构造、静态数据成员、静态成员函数、友元)
知识点学习 类 const作用 C语言的const限定符的含义为"一个不能改变值的变量",C++的const限定符的含义为"一个有类型描述的常量": const ...
- C++ 静态数据成员和静态成员函数
一 静态数据成员: 1.静态数据成员的定义. 静态数据成员实际上是类域中的全局变量.所以,静态数据成员的定义(初始化)不应该被放在头文件中,因为这样做会引起重复定义这样的错误.即使加上#ifndef ...
- C++基础(静态数据成员和静态成员函数)
[简介] 1.静态数据成员在类中声明,在源文件中定义并初始化: 2.静态成员函数没有this指针,只能访问静态数据成员: 3.调用静态成员函数:(1)对象.(2)直接调用: 4.静态成员函数的地址可用 ...
- C++中static修饰的静态成员函数、静态数据成员
1.静态成员函数.静态数据成员 在类中,用static修饰的成员函数被称为静态成员函数,而用static修饰的数据成员就称为静态数据成员:与普通的成员函数和数据成员不同, 静态成员函数和静态数据成员有 ...
- C++类静态数据成员与类静态成员函数
from:://http://blog.csdn.net/taina2008/article/details/1684834 把类中的函数都定义成静态函数,这样相当于在编译时就分配了空间,这样不需要实 ...
- 《挑战30天C++入门极限》C++类静态数据成员与类静态成员函数
C++类静态数据成员与类静态成员函数 在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? ...
- 转:C语言中的static变量和C++静态数据成员(static member)
转自:C语言中的static变量和C++静态数据成员(static member) C语言中static的变量:1).static局部变量 a.静态局部变量在函数内定义,生存期为整个程序 ...
- C++中静态数据成员
类的静态成员不能由类的构造函数来初始化.因为即使不存在类的任何对象时,类的静态成员依然存在并且可以被使用.类的静态成员也不能访问任何类的非静态成员. 类名和类对象都可以直接调用静态数据成员.因为静态数 ...
- 一个类的实例化对象所占空间的大小(对象大小= vptr(可能不止一个) + 所有非静态数据成员大小 + Aligin字节大小(依赖于不同的编译器))
注意不要说类的大小,是类的对象的大小. 首先,类的大小是什么?确切的说,类只是一个类型定义,它是没有大小可言的. 用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小. 如果 Class ...
随机推荐
- 原生js--userData
userData是IE5及其以上浏览器支持的一种客户端存储方式,它通过在document元素后面附加一个专属的元素来实现. 对userData的封装: /** * IE userdata封装 */fu ...
- 利用按钮打开tabBar页面
场景:当tabBar上有个人中心的时候,这里假设需要登陆才可以看到个人中心A页面,在A页面onload中先判断是否登陆,如果没有登陆就跳转到登陆页面B,待输入用户名和密码,点击登陆按钮后再跳转到A页面 ...
- 监控redis服务器执行的命令--类似于tomcat的local-access.log
一.问题由来 一般程序启动时会去拉必要的缓存存进去redis. 由于我们这边开发可直连开发和测试环境,有时候会发生,开发同学本地直连了测试环境,本地ide一启动,可能会导致重新覆盖了测试环境上的缓存. ...
- libxml2简单的生成、解析操作
3. 简单xml操作例子 link:http://www.blogjava.net/wxb_nudt/archive/2007/11/18/161340.html 了解以上基本知识之后,就可以进行一些 ...
- [转]Android Path里FillType功能
对于简单的封闭图形(路径无相交的现象),图形的外部和内部和容易判断,但如果路径有相交的情况,对应重叠的部分,使用不同的填充模式,内部和外部的定义有所不同.填充模式可以分为两类: EVEN_ODD 意味 ...
- 转sklearn保存模型
训练好了一个Model 以后总需要保存和再次预测, 所以保存和读取我们的sklearn model也是同样重要的一步. 比如,我们根据房源样本数据训练了一下房价模型,当用户输入自己的房子后,我们就需要 ...
- postgresql----网络地址类型和函数
本人对网络这块实在是搞不清楚,要是能有人推荐一下资料就好了!不知道有没有跟我一样呢?!所以在这里先贴一点从其他地方搞来的一些IPv4的东东. IPv4主要包括一下5类地址 A类: 0 7位 网络号 2 ...
- POJ-1157 LITTLE SHOP OF FLOWERS(动态规划)
LITTLE SHOP OF FLOWERS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 19877 Accepted: 91 ...
- CH0103最短Hamilton路径 & poj2288 Islands and Brigdes【状压DP】
虐狗宝典学习笔记: 取出整数\(n\)在二进制表示下的第\(k\)位 \((n >> ...
- Oracle备份恢复之数据库备份、还原、恢复理论
备份 冷备:关闭数据库并进行数据库物理文件的拷贝过程. 热备:数据库处于open阶段时的备份,通过指令将数据库文件头锁定,然后进行物理系统拷贝,然后通过指令解冻数据文件头,解冻后通过日志文件和undo ...