当前位置: 首页 > news >正文

为什么非const静态成员变量一定要在类外定义

当我们如下声明了一个类:

class A{public:static int sti_data;// 这个语句在c++11前不能通过编译,在c++11的新标准下,已经能够在声明一个普通变量是就对其进行初始化。int a = 10static const int b = 1;//...其他member
};// 在类外定义静态成员变量并分配内存
int A::sti_data = 10;

上述的类只是声明了而已,并不是在系统中实际存在,要使用一个类,必须在系统中分配内存,也就是实例化出一个对象,比如:

int main () {A a;
}

为了明白为什么类的非const静态变量一定要在类的外边定义:

  • 首先,需要搞清楚,文件中的类A的写法只是声明类A实现形式,在我们没有实例化一个类对象前,系统中不存在分配给类A的内存。同理,我们实例化了N个类A的对象,系统分配了N个A大小的内存。
  • 其次,静态数据成员是一个类共有的,而不是一个对象独有,整个程序中只有一份静态数据成员的内存。
  • 假如,我们不对静态成员变量进行与普通成员变量不同的处理,而是一样能在类的声明里事先定义并初始化好静态成员变量(也就是声明时给定一个初始值,等真正实例化一个对象时便用事先给定的初始值初始化这个变量):static int sti_data = 1;,这意味着,每个我们实例化的类对象,都存在一个分配给静态成员变量的内存,这将导致在内存中存在多个同名的静态变量,这与静态变量的唯一性矛盾,必然编译不通过。
  • 从实现来看,编译器确实能做到,每次实例化一个类对象时判断类中的静态变量是否已经定义过,但很显然,这么做的成本太高,还不如直接强制要求不能在类中对非const静态变量进行定义并初始化,而是只能声明。
  • 至于为什么const静态变量能够在类内直接定义,因为static const 成员变量会被编译器优化,为编译期常量,编译器不会为其分配内存,更像是宏定义那样,在编译期时,在使用它的地方,用它的值替换它,这一点可以通过代码看到,若我们在类中定义一个static const 成员变量,我们可以打印出它的值,却不能打印出它的地址,因为编译器并没有给它分配内存。
  • 因此,c++要求,非const静态变量一定要在类外定义。

为什么(普通或类的)函数里的静态变量能够事先初始化
这个问题主要时为了与第一个问题进行对比,加深理解。
原因很简单,每个的函数,无论是否静态,是否是成员函数还是普通函数,程序在编译时,会给每个函数分配内存,同时一个函数在程序里只有一份内存,这与类在实例化一个对象时才分配内存是有本质上的区别的。这时,对于函数的静态变量而言,只需要把静态变量的内存分配到静态区就能做到在程序的生命周期里不随着函数的调用而被构造或者销毁。

http://www.lryc.cn/news/198073.html

相关文章:

  • 千兆光模块和万兆光模块的区别?
  • 中断:Zynq Uart中断的流程和例程~UG585的CH.19
  • 计算机补码能够减法转加法的原因
  • 软件工程与计算总结(十九)软件测试
  • Tomcat设置IP黑名单和白名单server.xml
  • 【AI视野·今日NLP 自然语言处理论文速览 第五十五期】Mon, 16 Oct 2023
  • k8s crd设置额外header
  • 电容笔好还是触屏笔好?便宜又好用的电容笔推荐
  • 列表作为条件查询的参数
  • elementui中el-select和el-tree实现下拉树形多选功能
  • 手机怎么监控电脑?
  • 职场题:有一件特别紧急的事,群众要办理,且联系不上领导,你怎么办?(2)
  • 《深入理解java虚拟机 第三版》学习笔记一
  • webGL编程指南 第三章 旋转三角形
  • 网络安全是什么?一文认识网络安全
  • LeetCode 2897. 对数组执行操作使平方和最大【贪心,位运算,哈希表】2301
  • linux加密安全和时间同步
  • 在Go中处理异常
  • rust 全局变量
  • 使用Python的qrcode库生成二维码
  • MSQL系列(四) Mysql实战-索引分析Explain命令详解
  • FPGA软件【紫光】
  • 饲料化肥经营商城小程序的作用是什么
  • AI系统ChatGPT源码+详细搭建部署教程+支持GPT4.0+支持ai绘画(Midjourney)/支持OpenAI GPT全模型+国内AI全模型
  • vue项目优雅降级,es6降为es5,适应低版本浏览器渲染
  • 运放供电设计
  • vue2-org-tree 树型结构的使用
  • 【计算机网络】(面试问题)路由器与交换机的比较
  • 基于下垂控制的孤岛双机并联逆变器环流抑制模型(Simulink仿真实现)
  • 第十九章 文件操作