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

详解C++作用域与生命周期

Pascal之父Nicklaus Wirth曾经提出一个公式,展示出了程序的本质:程序=算法+数据结构。后人又给出一个公式与之遥相呼应:软件=程序+文档。这两个公式可以简洁明了的为我们展示程序和软件的组成。

程序的运行过程可以理解为算法对数据的加工过程,程序的运行的结果,就是算法加工数据产生的结果数据。算法描述的是对数据加工的步骤,对应于程序中的函数。数据结构描述的是数据在计算机中的组织结构,对应于程序中的数据类型。程序中数据对应的就是无处不在变量。对于我们编程人员,面对的无非就是函数,数据类型和变量。因此,C++谈及作用域与生命周期针对的就是这三大程序的组成要素:函数、数据类型和变量。下面将一一讲述。

1.作用域与生命周期的区别

作用域与生命周期是两个完全不同的概念。在英文中,作用域用“scope”表示,生命周期则用“duration”表示。作用域是一个静态概念,只在编译源程序的时候用到。一个标识符的作用域指在源文件中该标识符能够独立地合法出现的区域。生命周期则是一个运行时(Runtime)概念,它是指一个变量在整个程序从载入到结束运行的过程中存在的时间周期。由于函数和数据类型是静态的概念,它们没有生命周期的说法,它们从编译、程序的运行到结束整个过程是一直存在的。

C++中作用域的级别由高到低,主要有文件域(全局作用域)、名字空间域、类域、函数作用域和代码块作用域,其中函数作用域和代码块作用域又统称为局部域。

2.函数的作用域

函数分为类的成员函数和全局函数。

类的成员函数:

  • 作用域:类域。
  • 生命周期:无(程序运行期一直存在)。
  • 引用方法:其他文件中要使用点操作符(.)或指针操作符(->)或作用域运算符(::)来引用。
  • 内存分布:代码区。
  • 注意:类成员函数可以定义在类体内,即定义在头文件,当类被不同源文件包含时不会报重定义的错误,因为类体内实现的函数具有inline特性。

举例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

//main.cpp

classtest

{

private:

inti;

public:

voidshow()

{

cout<<"i:"<<i<<endl;

}

};

intmain(intargc,char* argv[])

{

test t;

t.show()

}

全局函数:

  • 作用域:文件域(全局作用域)。
  • 生命周期:无(程序运行期一直存在)。
  • 引用方法:其他文件中要先进行函数原型声明,再使用。
  • 内存分布:代码段。
  • 注意:如果在两个源文件中定义了同名的全局函数,连接时会出现重定义错误。

举例如下:

1

2

3

4

5

6

7

8

9

10

11

12

//function.cpp

voidprintHello()

{

cout<<"hello world"<<endl;

}

//main.cpp

voidprintHello();

intmain(intargc,char* argv[])

{

printHello();

}

3.数据类型的作用域

C++中的数据类型分为基本数据类型和非基本数据类型,非基本数据类型中又分为复合数据类型和构造数据类型。关于C++中的数据类型,详见本人另一篇blog: C++数据类型。

基本数据类型:
基本数据类型包括整型(int)、实型(float和double)、字符型(char)、布尔型(bool)和无值型(void)。

  • 作用域:文件域(全局作用域)。
  • 生命周期:无(程序运行期一直存在)。
  • 引用方法:无需申明,直接使用。
  • 内存分布:代码段。

复合数据类型:

复合数据类型包括:数组(type[])、指针(type*)、引用(type&)、枚举(enum)。

如果复合数据类型是构造数据类型参与的复合,其作用域与构造数据类型一致。enum枚举类型的作用域与构造类型相同。

构造数据类型:

  • 作用域:类型定义所在的域,其他文件不可见。
  • 生命周期:无(程序运行期一直存在)。
  • 引用方法:其他文件中要先进行定义,再通过作用域运算符进行使用。
  • 内存分布:代码区。
  • 注意:只要文件不互相包含,如果在两个源文件中定义了同名的构造,不会出现重定义错误,因为数据类型不具有外部连接性。

举例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

//main.cpp

namespacedd

{

classtest

{

private:

inti;

public:

voidshow()

{

cout<<"i:"<<i<<endl;

}

};

}

usingnamespacedd;//引用命名空间域中的构造类型test,否则无法使用

intmain(intargc,char* argv[])

{

test t;

t.show();

}

4.变量的作用域与生命周期

我们面对的变量主要分为全局变量、全局静态变量、局部变量和局部静态变量。下面一一讲述他们的作用域与生命周期。

http://www.jsqmd.com/news/832658/

相关文章:

  • Kubernetes持久化存储实战
  • 智能体操作系统agentOS:构建可编排、可观测的AI智能体生产平台
  • FRAME技术:实时自中心运动捕捉在VR/AR中的突破
  • Adafruit ItsyBitsy M0 Express开发板:双模编程与硬件全解析
  • 【2026最新】鸿蒙NEXT性能优化实战:培训班管理系统启动、内存、渲染全方位优化
  • Elastic 开源社区行为准则
  • 5分钟精通GPX编辑:零基础打造专业轨迹地图的终极指南
  • Arduino红外遥控数字温度计:从传感器到LCD显示的嵌入式实践
  • 别再只懂JPEG了!深入聊聊SVD图像压缩的优缺点与适用场景(Python实战分析)
  • 本地优先与双链笔记:构建个人知识管理系统的核心原理与实践
  • 婚礼项目管理与沟通技巧:从预算控制到供应商谈判全攻略
  • 基于Go与Web技术的开源堡垒机OpenClaw Bastion部署与安全实践
  • 在Windows电脑上运行Android应用的终极指南:WSABuilds全面解析
  • 在VSCode插件里用上了!手把手教你将Tree-sitter集成到Python项目做实时语法检查
  • JIT智慧工地物料配送路径优化【附代码】
  • 用PyTorch复现PraNet息肉分割模型:从Res2Net骨干到反向注意力模块的保姆级代码解读
  • 基于面部视频的非接触式心率检测:affect-pulse-ai项目原理与实战
  • 嵌入式动画优化:DMA驱动位图渲染在SAMD21上的实现
  • LoRa无线通信实战:从RFM9X模块初始化到远距离通信优化
  • 关键词优化怎么理解最清楚
  • 一键部署实战指南:从Docker Compose到Kubernetes的自动化部署方案
  • 基于MLX90640与Python的嵌入式热成像开发实战
  • 对比自行维护API密钥Taotoken在管理便捷性上的优势
  • Adafruit支付升级Stripe集成:安全保存支付方式与快速结账指南
  • 量子模拟中的噪声与误差:Trotter算法优化策略
  • 模拟WiFi反向散射技术:无电池物联网通信新突破
  • 基于温度感应的智能吊坠:从传感器到动画显示的嵌入式实践
  • Arm Neoverse CMN-700互连架构与寄存器编程详解
  • 2026年知名的开关用改性新材料/家电用改性新材料/浙江PC改性新材料厂家精选合集 - 行业平台推荐
  • AI会话上下文智能压缩:突破LLM长度限制的工程实践