在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。

静态成员的定义或声明要加个关键static。静态成员可以通过双冒号来使用即<类名>::<静态成员名>。

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象。希望阅读本文可以使读者对类的静态成员变量和成员函数有更为深刻的认识。

第一个例子,通过类名调用静态成员函数和非静态成员函数

  1. class Point
  2. {
  3. public:
  4. void init()
  5. {
  6. }
  7. static void output()
  8. {
  9. }
  10. };
  11. void main()
  12. {
  13. Point::init();
  14. Point::output();
  15. }

编译出错:error C2352: 'Point::init' : illegal call of non-static member function

结论1:不能通过类名来调用类的非静态成员函数。

第二个例子,通过类的对象调用静态成员函数和非静态成员函数

将上例的main()改为:

  1. void main()
  2. {
  3. Point pt;
  4. pt.init();
  5. pt.output();
  6. }

编译通过。

结论2:类的对象可以使用静态成员函数和非静态成员函数。

第三个例子,在类的静态成员函数中使用类的非静态成员

  1. #include <stdio.h>
  2. class Point
  3. {
  4. public:
  5. void init()
  6. {
  7. }
  8. static void output()
  9. {
  10. printf("%d\n", m_x);
  11. }
  12. private:
  13. int m_x;
  14. };
  15. void main()
  16. {
  17. Point pt;
  18. pt.output();
  19. }

编译出错:error C2597: illegal reference to data member 'Point::m_x' in a static member function

因为静态成员函数属于整个类,在类实例化对象之前就已经分配空间了,而类的非静态成员必须在类实例化对象后才有内存空间,所以这个调用就出错了,就好比没有声明一个变量却提前使用它一样。

结论3:静态成员函数中不能引用非静态成员。

第四个例子,在类的非静态成员函数中使用类的静态成员

  1. class Point
  2. {
  3. public:
  4. void init()
  5. {
  6. output();
  7. }
  8. static void output()
  9. {
  10. }
  11. };
  12. void main()
  13. {
  14. Point pt;
  15. pt.output();
  16. }

编译通过。

结论4:类的非静态成员函数可以调用用静态成员函数,但反之不能。

第五个例子,使用类的静态成员变量

  1. #include <stdio.h>
  2. class Point
  3. {
  4. public:
  5. Point()
  6. {
  7. m_nPointCount++;
  8. }
  9. ~Point()
  10. {
  11. m_nPointCount--;
  12. }
  13. static void output()
  14. {
  15. printf("%d\n", m_nPointCount);
  16. }
  17. private:
  18. static int m_nPointCount;
  19. };
  20. void main()
  21. {
  22. Point pt;
  23. pt.output();
  24. }

按Ctrl+F7编译无错误,按F7生成EXE程序时报链接错误

error LNK2001: unresolved external symbol "private: static int Point::m_nPointCount" (?m_nPointCount@Point@@0HA)

这是因为类的静态成员变量在使用前必须先初始化。

在main()函数前加上int Point::m_nPointCount = 0;

再编译链接无错误,运行程序将输出1。

结论5:类的静态成员变量必须先初始化再使用。

结合上面的五个例子,对类的静态成员变量和成员函数作个总结:

一。静态成员函数中不能调用非静态成员。

二。非静态成员函数中可以调用静态成员。因为静态成员属于类本身,在类的对象产生之前就已经存在了,所以在非静态成员函数中是可以调用静态成员的。

三。静态成员变量使用前必须先初始化(如int MyClass::m_nNumber = 0;),否则会在linker时出错。

再给一个利用类的静态成员变量和函数的例子以加深理解,这个例子建立一个学生类,每个学生类的对象将组成一个双向链表,用一个静态成员变量记录这个双向链表的表头,一个静态成员函数输出这个双向链表。

  1. #include <stdio.h>
  2. #include <string.h>
  3. const int MAX_NAME_SIZE = 30;
  4. class Student
  5. {
  6. public:
  7. Student(char *pszName);
  8. ~Student();
  9. public:
  10. static void PrintfAllStudents();
  11. private:
  12. char    m_name[MAX_NAME_SIZE];
  13. Student *next;
  14. Student *prev;
  15. static Student *m_head;
  16. };
  17. Student::Student(char *pszName)
  18. {
  19. strcpy(this->m_name, pszName);
  20. //建立双向链表,新数据从链表头部插入。
  21. this->next = m_head;
  22. this->prev = NULL;
  23. if (m_head != NULL)
  24. m_head->prev = this;
  25. m_head = this;
  26. }
  27. Student::~Student ()//析构过程就是节点的脱离过程
  28. {
  29. if (this == m_head) //该节点就是头节点。
  30. {
  31. m_head = this->next;
  32. }
  33. else
  34. {
  35. this->prev->next = this->next;
  36. this->next->prev = this->prev;
  37. }
  38. }
  39. void Student::PrintfAllStudents()
  40. {
  41. for (Student *p = m_head; p != NULL; p = p->next)
  42. printf("%s\n", p->m_name);
  43. }
  44. Student* Student::m_head = NULL;
  45. void main()
  46. {
  47. Student studentA("AAA");
  48. Student studentB("BBB");
  49. Student studentC("CCC");
  50. Student studentD("DDD");
  51. Student student("MoreWindows");
  52. Student::PrintfAllStudents();
  53. }

程序将输出:

http://blog.csdn.net/morewindows/article/details/6721430

C++ 类的静态成员详细讲解(转)的更多相关文章

  1. 05-- C++ 类的静态成员详细讲解

     C++ 类的静态成员详细讲解    在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不 ...

  2. 面向对象课后深入学习(C++ 类的静态成员详细讲解)

    今天在刚申请了博客,一下午都在写那个随笔,所以说好的来看c++的也放在了最后,下星期就考试了,这个类的静态成员是我不是很懂的,在网上 看到一片很详细的博客考下来回去慢慢看. 在C++中,静态成员是属于 ...

  3. C++ 类的静态成员详细讲解

    在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节 ...

  4. C++ 类的静态成员详细讲解[转]

    在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节 ...

  5. 转:C++ 类的静态成员详细讲解

    在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节 ...

  6. 简单Java类 全网最详细讲解 !!!

    最近学习java非常吃力,学习的进度很快,由于基础没打牢固,整体上项目理解很吃力,偶尔会遇到一些基本的概念,都会阻碍整体的理解.最近也看了不少的视频讲解,听得很迷,最后搞得很乱,没有明确的学习目标,今 ...

  7. 【Cocos2d-X开发学习笔记】第12期:动作类CCAction的详细讲解

    一般对于游戏中的精灵而言,它们不仅仅是存在于场景中,而且是动态展现的,例如,精灵移动的动态效果.动 画效果.跳动效果.闪烁和旋转动态效果等.每一种效果都可以看成是精灵的一个动作. 一.动作类(CCAc ...

  8. [VC++]用CTime类得到当前日期、时间、星期,格式化(详细讲解)

    用CTime类得到当前日期.时间.星期,格式化(详细讲解)2009/05/12 09:48 A.M.① 定义一个CTime类对象 CTime time; ② 得到当前时间 time = CTime:: ...

  9. 第四节:详细讲解Java中的类和面向对象思想

    前言 大家好,给大家带来详细讲解Java中的类和面向对象思想的概述,希望你们喜欢 类和面向对象 在Java中怎样理解对象,创建对象和引用:什么是引用,对于基础学习的同学,要深入了解引用.示例:Stri ...

随机推荐

  1. JSP的那些事儿(2)---- DWR2.0 的配置和使用

    JSP的那些事儿(2)----DWR2.0 的配置和使用 分类: Web开发 JAVA 2009-04-23 15:43 999人阅读 评论(0) 收藏 举报 jspdwrjavascriptserv ...

  2. javascript中的splice方法介绍&示例

    javascript 中的 splice 方法很强大,它可以用于插入.删除或替换数组的元素. 下面来一一介绍! 删除:用于删除元素,两个参数,第一个参数(要删除第一项的位置),第二个参数(要删除的项数 ...

  3. 云时代基础设置自动化管理利器: Chef

    云时代的到来势不可挡.尤其作为程序员,我们每天或多或少的直接或间接的使用者各种云服务.云平台有很多种,如云软件(SaaS, Software as a service).云平台(PaaS, Platf ...

  4. Maven之Hello World入门实例

    1.使用eclipse创建maven工程在eclipse中,选择新建工程的时候,选择other,找到maven 下一步,下一步,直到出现类似如下图片点击finish即可完成maven工程创建. 运行的 ...

  5. Spring 依赖注入控制反转实现,及编码解析(自制容器)

    定义: 在运行期,由外部容器动态的将依赖对象动态地注入到组件中. 两种方式: 手工装配 -set方式 -构造器 -注解方式 自动装配(不推荐) 1利用构造器 2set方法注入 dao: package ...

  6. 狗日的js的闭包

    一.变量的作用域 要懂得闭包,起首必须懂得Javascript特别的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript说话的特别之处,就在于函数内部可以直接读取全局变量 ...

  7. 使用SVG生成的奔跑吧兄弟的动画效果

    在线演示 本地下载 缩放一下在线演示效果窗口,看看不同大小下的动画是不是都显示的非常完美? 体验一下SVG的强大之处吧!

  8. 负margin在布局中的运用

    一.左右栏宽度固定,中间栏宽度自适应 <!DOCTYPE html> <html> <head lang="en"> <meta char ...

  9. SQL Server如何提高数据库备份的速度

    对于一个数据库完整备份来说,备份的速度很大程度上取决于下面两个因素:读磁盘数据.日志文件的吞吐量,写磁盘数据文件的吞吐量. 下图是备份过程中磁盘的变化情况: 读吞吐量 读吞吐量的大小取决于磁盘读取数据 ...

  10. mac 命令行 安装 需要管理员 权限

    Please try running this command again as root/Administrator. sudo chown -R $USER /usr/local