鸡啄米在上一讲数据和函数中讲到,函数之间共享数据也就是此函数访问彼函数的数据主要是通过局部变量、全局变量、类的数据成员、类的静态成员及友元实现的,前三个已经讲过了,这一讲鸡啄米来讲讲静态成员。静态成员包括静态数据成员和静态函数成员。

1.静态数据成员

之前讲到的类的数据成员都是一个对象一个拷贝,每个对象都有自己的数据成员的值,但有时候我们需要让某个类的所有对象共享某个数据成员,比如我们有一个学生类CStudent,其中有学号、姓名等数据成员,如果我们想要对学生人数进行统计,那么这个数据应该放在哪里呢?放在类外的某个地方的话数据的隐藏性就不好了。可能有朋友就说了,可以在类中增加一个数据成员存放学生人数,但这样就有两个坏处,第一,该类的每个对象都将有一个这个数据成员的副本,浪费内存;第二,学生人数可能在不同的对象中有不同的数,不一致了。这个时候就需要静态数据成员了。

静态数据成员存放的是类的所有对象的某个共同特征的数据,对于每个对象而言,该数据都是相同的,在内存中只存在一份。这与类的一般数据成员不同,一般数据成员会在每个对象中都有一个拷贝,每个拷贝的值可能都不一样。静态数据成员由类的所有对象共同维护和使用,这样就实现了类的对象间的数据共享。

声明静态数据成员的方式与一般数据成员不同的是,其前面要加static关键字,比如static int x;。静态数据成员具有静态生存期。它可以通过类名或对象名访问。用类名直接访问的方式为:类名::标识符。在类的声明中仅对静态数据成员进行引用性说明,就是带static的声明,必须在其文件作用域的其他地方进行定义性说明,也可以进行初始化,如果不显式初始化的话会将此静态数据成员初始化为0。

对于静态数据成员鸡啄米给大家一个例程:

#include

using namespace std;

class CStudent         // 学生类的声明

{

public:

CStudent(int nID)    { m_nID = nID; m_nCount++; }       // 构造函数

CStudent(CStudent &s);                                 // 拷贝构造函数

int GetID(){ return m_nID;}

void GetCount()       { cout<

private:

int m_nID;

static int m_nCount;                                    // 静态数据成员的引用性说明

};

CStudent::CStudent(CStudent &s)

{

m_nID = s.m_nID;

m_nCount ++;

}

int CStudent::m_nCount=0;                                       // 静态数据成员的定义性说明及初始化

int main()

{

CStudent A(6);             // 定义对象A

cout<

A.GetCount();               // 输出此时学生个数

CStudent B(A);            // 定义对象B,并用A初始化B

cout<

B.GetCount();

return 0;

}

当然学生的学号不可能一样,这里只是举个例子。类CStudent的静态数据成员m_nCount用来给学生人数计数,定义一个新的学生对象,它的值就加1。这里初始化的时候要注意,必须用类名来引用,还有就是此数据成员的访问控制属性,这里m_nCount声明为私有类型,初始化时可以直接访问,但是在主函数内就不能直接访问了。

在对象A声明时,调用构造函数,m_nCount加1,对象B声明时,调用拷贝构造函数,m_nCount又加1,两次都访问的A和B共同维护的静态数据成员,这样就实现了对象间的数据共享。上面的运行结果是:

学生A,6 学生人数:1

学生B,6 学生人数:2

2.静态函数成员

上面的学生类中,GetCount函数用来输出静态数据成员m_nCount,我们想输出m_nCount时就要通过学生类的某个对象调用GetCount函数来实现。但是,在定义任何对象之前,m_nCount是有初始值的,那我们怎样输出这个初始值呢?因为没有定义任何对象,就没法通过对象调用GetCount。m_nCount是私有的,也不能用类名直接引用。因为m_nCount是类的所有对象共有的,那我们希望不通过对象直接用类名调用函数来显示m_nCount,这就要用到静态成员函数了。

静态成员函数跟静态数据成员一样,也是由类的所有对象所共有,由他们共同维护和使用。声明时前面也要加static关键字,比如,static void fun(void);。我们可以通过类名或对象名调用公有类型的静态成员函数,而非静态成员函数只能由对象名调用。

静态成员函数可以访问该类的静态数据成员和其他静态成员函数,如果要访问非静态数据成员,则必须将对象作为参数传递进去,然后通过传进去的对象名来访问。鸡啄米给大家举个例子:

class A

{

public:

static void f(A a);

private:

int x;

};

void A::f(A a)

{

cout<

cout<

}

所以静态成员函数访问非静态成员很麻烦,它一般用来访问全局变量和同一个类中的静态数据成员。

鸡啄米把上面学生类的GetCount函数改成静态成员函数大家看下:

#include

using namespace std;

class CStudent         // 学生类的声明

{

public:

CStudent(int nID)    { m_nID = nID; m_nCount++; }       // 构造函数

CStudent(CStudent &s);                                 // 拷贝构造函数

int GetID()                 { return m_nID;}

static void GetCount(){ cout<

private:

int m_nID;

static int m_nCount;                                    // 静态数据成员的引用性说明

};

CStudent::CStudent(CStudent &s)

{

m_nID = s.m_nID;

m_nCount ++;

}

int CStudent::m_nCount=0;                                       // 静态数据成员的定义性说明及初始化

int main()

{

CStudent A(6);                        // 定义对象A

cout<

A.GetCount();                         // 输出此时学生个数

CStudent B(A);                       // 定义对象B,并用A初始化B

cout<

CStudent::GetCount();

return 0;

}

大家可以比较的看下两个例子,学生类的声明只有一点不同,就是GetCount前加了static将其改为了静态成员函数,主函数中就可以通过类名或对象名调用静态成员函数,就像上面的A.GetCount()和CStudent::GetCount(),大家也可以把A.GetCount()改成CStudent::GetCount(),或者把CStudent::GetCount()改成B.GetCount()试下,运行结果应该是一样的。

静态成员的好处就是内存中只有一份拷贝,可以直接通过类名访问。鸡啄米今天就讲到这了,下一讲给大家讲讲友元。

除非特别注明,鸡啄米文章均为原创

2011年10月10日

作者:鸡啄米

浏览:

c语言类静态数据成员函数,鸡啄米:C++编程入门系列之二十一(C++程序设计必知:类的静态成员)...相关推荐

  1. 静态数据成员和静态数据成员函数

    c++中的static静态数据成员和静态成员函数应该是让大家比较头疼的东西,好像也是找工作公司面试中常常问到的东西.我自己也深有体会,在学习c++的过程中,总感觉static很烦人,但是又是一个必须懂 ...

  2. 类静态数据成员的定义及初始化

    #include <iostream> using namespace std; /* 在 C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有 对象共用.所以在所 ...

  3. 鸡啄米:C++编程入门系列之二(原码、反码与补码)

    转载自: http://www.jizhuomi.com/software/23.html 上一节进制数中鸡啄米讲了二进制.八进制.十进制和十六进制数的表示方法和相互转换关系.这节主要讲解二进制的几种 ...

  4. 类的静态数据成员和静态成员函数

    一.什么是类的静态成员 静态成员变量和全局变量都存储在全局/静态区,它们都是在程序编译时创建,直到编译结束才被收回.所以全局变量和静态成员变量的功能差不多,只是创建的方式不同,类的静态成员创建在类中, ...

  5. 类的静态数据成员和静态成员函数浅析

    一.静态数据成员        类中的数据成员声明前加上static,则表示该数据成员为静态数据成员.除了与其他数据具有相同的public/private/protect访问属性外,还有一些其他的属性 ...

  6. c++远征之模板篇——静态数据成员,静态成员函数

    以下内容源于慕课网的学习整理,如有侵权,请告知删除. 1.静态数据成员 (1)不同于普通的数据成员,静态数据成员在没有实例化时,它也是存在的(即它是和类共存的): (2)它一般不依赖于构造函数的初始化 ...

  7. C++:静态成员函数访问静态数据成员(商店实际应用题)

    题目概述: 编程: #include< iostream> using namespace std; class Product { public: Product(int n, int ...

  8. C++——静态数据成员及静态成员函数

    1.静态数据成员 1.在类内数据成员前加上 static 关键字,即为静态数据成员 2.对于类静态数据成员,无论有多少个该类的对象,该静态数据成员在内存中只有一份拷贝(其他普通数据成员,每个类对象都有 ...

  9. 静态数据成员(C++)

    目录 一.静态数据成员 1.1.定义 1.2.声明 1.3.初始化 1.4.普通访问 1.5.对象访问 二.静态成员函数 一.静态数据成员 1.1.定义 我们都知道,类是对具有相同属性和相同行为的一组 ...

最新文章

  1. elasticdump安装_elasticsearch导出、导入工具-elasticdump
  2. knockout的使用
  3. C++ STL中set底层实现方式
  4. vue php 分页组件,基于Vue.js的表格分页组件
  5. docker镜像启动后端口号是多少_java项目docker云化入门
  6. Initializer Lists
  7. 测试(一)试题及答案
  8. 图文详细解说DevExpress 2015新版亮点【附文档下载】
  9. 听听各位对Ubuntu的UI的看法
  10. python中match用法_Python3.9.1中使用match方法详解
  11. 2020最新中高阶Android面试题总结-上(附解题思路)
  12. iOS中WKWebView清除cookies
  13. shap库源码和代码实现
  14. 体育直播数据网站如何运营
  15. 学人工智能必备的数学课,再也不怕学AI了
  16. android ftp 链接不上去,安卓手机无法连接电脑上的ftp(vsftpd)服务器
  17. 【Vue项目实战】Vue3动画神操作!教你如何实现PPT一样的动画效果!
  18. vue3开发实践总结
  19. 灰度共生矩阵的原理及代码实现(python)
  20. Python中使用,YOLOv5实现视觉识别螺丝

热门文章

  1. 国庆假期带动新能源汽车消费热潮
  2. 特斯拉全球超级充电站已超过25000座 国内超过870座
  3. 开工第一天,老板补发年终奖,一箱18元的冰棍
  4. “买苹果辞退,买华为补贴”,这家公司支持国产手机的理由给我惊到了!
  5. 京东股价创新高:市值首次突破千亿美元 !
  6. 董明珠自媒体:格力口罩今日开售 上午预约下午抢购
  7. 比1亿像素还要更厉害!三星Galaxy S11相机应用代码泄露天机...
  8. 一加8 Pro渲染图曝光:骁龙865+挖孔屏+后置四摄
  9. 老实人做不得?教练微信工作群内“说错话”遭公司索赔46万元
  10. 停机断网也能充话费了!微信和三大运营商打造绿色通道:太方便了!