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

C++ 警惕 头文件中的static变量 如果说 全局变量“不受时间和空间限制”,那static变量是“不受时间限制,但受空间限制”。“不受时间限制”是指到程序运行结束时才释放,“受空间限制”是指 仅能在特定的作用域中使用。头文件中的全局变量,可以被引用该头文件的源文件共享;而头文件中的static变量,不能被引用该头文件的源文件共享,这些源文件中的同名static变量彼此独立。下面是一个代码示例。照此理解,应优先考虑使用static变量而非全局变量,前者“权限”更小,更安全。 阅读详情

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

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

程序将输出:

当然在本例还可以增加个静态成员变量来表示链表中学生个数,如果读者有兴趣,就将这个作为小练习吧。

原文地址:http://blog.youkuaiyun.com/morewindows/article/details/6721430

Java实训:学生信息管理系统 Java,实训项目,学生信息管理系统 阅读详情

相关推荐

CDO批量处理nc文件:5分钟搞定CMIP6数据双线性插值(附完整代码)

本文详细介绍了如何使用CDO工具链中的`remapbil`命令,快速实现CMIP6数据的批量双线性插值处理。通过环境配置、核心操作步骤、高级优化技巧及典型报错解决方案,帮助科研人员高效处理大规模nc文件,显著提升气象数据处理效率。

weixin_29267307的博客 292

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

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

MoreWindows Blog 11万+

ST7789驱动实战:从SPI时序到RGB565显示的完整配置解析

本文详细解析了ST7789液晶驱动芯片的SPI时序配置与RGB565显示实现,从数据手册解读到代码实战,涵盖SPI接口配置、关键寄存器设置及完整初始化流程。通过优化DMA传输和常见问题排查,帮助开发者高效驱动ST7789显示屏,适用于嵌入式显示项目开发。

weixin_29162439的博客 184

linux C++ 类的静态成员函数与非静态成员函数的互访

前言:对象与对象之间的成员变量是相互独立的。要想共用数据,则需要使用静态成员和静态方法。只要在类中声明静态成员变量,即使不定义对象,也可以为静态成员变量分配空间,进而可以使用静态成员变量。(因为静态成员变量在对象创建之前就已经被分配了内存空间)静态成员变量虽然在类中,但它并不是随对象的建立而分配空间的,也不是随对象的撤销而释放(一般的成员在对象建立时会分配空间,在对象撤销时会释放)。静态成员变量是...

北雨南萍 3453

计算机网络实验(华为eNSP模拟器)——第十章 Eth-Trunk(链路聚合)

目录一、Eth-Trunk的定义二、Eth-Trunk的工作模式(一)LACP模式1、定义2、命令(二)手工负载分担模式1、定义2、命令三、结语 一、Eth-Trunk的定义 Eth-Trunk是指设备的链路聚合,即将该设备的多个接口捆绑成一个接口,从而达到了增加带宽和提高可靠性的目的。我们要注意它是将多条物理链路,在逻辑上合并成一条,而不是串在一起。例我们将LSW1交换机S5700的三个端口(即GE0/0/1 、GE0/0/2、GE0/0/3)定义为一个Eth-Trunk接口与LSW2交换机相连,如下:

小宇y的博客 8417

SAP IDOC与EDI实战解析:从基础原理到跨系统采购订单同步

本文深入解析了SAP IDOC与EDI在企业数据交换中的核心作用,通过跨系统采购订单同步的实战案例,详细阐述了从基础原理到配置部署的全过程。文章将IDOC比作标准化数据“集装箱”,EDI视为高效传输“高速公路”,并提供了从消息类型定义、处理代码开发到全链路测试的完整指南,帮助企业实现自动化、无差错的业务协同。

weixin_28335283的博客 294

C++静态成员

在同类的多个对象之间实现数据共享,往往使用静态成员而不是全局变量。 C++静态数据成员 1.1静态数据成员是一种特殊的数据成员。static int height; 1.2静态数据成员可以通过类名来引用,也可以通过对象来引用。 1.3静态数据成员不属于某一个对象,静态数据成员的存储空间是在静态存储区的,与一般的对象不同。 1.4静态数据成员和对象的建立与销毁没有直接的关系,静态数据成

海贼王 1万+

手把手教你用OpenCore在Dell Optiplex 3060上安装黑苹果(含ALC255声卡修复)

本文提供了一份详尽的指南,教你如何在Dell Optiplex 3060微型台式机上安装黑苹果系统。文章重点解决了使用OpenCore引导时的核心配置,特别是针对Intel UHD 630核显的驱动优化和Realtek ALC255声卡的修复方案,旨在帮助用户打造一个稳定可用的macOS工作站。

weixin_29275257的博客 789

C++类的静态成员初始化详细讲解

记住:通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化!!! 复制代码 代码如下: #include using namespace std; class test { public: static int num; }; int test::nu

MTT_SKY 8309

UNet改进(19):基于残差注意力模块Residual Attention的高效分割网络设计

本文提出一种结合注意力机制的改进UNet网络,通过引入残差注意力模块(ResidualAttentionBlock)增强医学图像分割性能。该网络在传统UNet的U型结构基础上,创新性地将轻量级注意力机制与残差连接相结合,在编码器-解码器各层级实现特征重标定。改进后的网络具有三方面优势:通过注意力机制自适应聚焦关键特征区域,利用残差连接缓解梯度消失问题,采用模块化设计灵活配置注意力位置。

2501_91516851的博客 780

Dify知识库文档批量下载神器:一键导出所有文件到本地

在使用Dify进行知识库管理的过程中,我们经常遇到一个实际问题:如何将已上传到知识库中的文档批量下载到本地?目前Dify的管理界面虽然功能强大,但暂时没有提供直接的UI界面来批量导出或下载知识库内的文档。这意味着如果我们需要将知识库中的文件备份到本地或进行离线处理,只能通过API接口来实现。本文将详细介绍如何利用Dify的REST API构建一个完整的知识库文档下载解决方案,这也是目前实现知识库文件批量下载到本地的唯一可行路径。🎉进入大模型应用与实战专栏 | 🚀查看更多专栏内容首先,我们需要在Dify的

羊城迷鹿的博客 3473
上一篇: 位运算
下一篇: 需要友元的原因及使用
大老鼠
博客等级 码龄15年 14粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值