内联变量(inline variables):在多个文件中共享全局常量
在 C++17 中,引入了 内联变量(inline variables) 的概念,可以用于在多个文件中共享全局常量。内联变量允许在头文件中定义变量,而不会导致链接错误(如重复定义)。这种方式非常适合用于定义跨多个文件共享的全局常量。
使用内联变量共享全局常量的步骤
-
在头文件中定义内联变量:
- 使用
inline
关键字定义全局常量。 - 将头文件包含在需要使用该常量的源文件中。
- 使用
-
在源文件中使用常量:
- 直接使用头文件中定义的常量。
示例代码
头文件 constants.h
#ifndef CONSTANTS_H
#define CONSTANTS_H// 定义内联全局常量
inline constexpr int MAX_VALUE = 100;
inline constexpr double PI = 3.14159;
inline constexpr const char* APP_NAME = "MyApp";#endif // CONSTANTS_H
源文件 main.cpp
#include <iostream>
#include "constants.h"int main() {std::cout << "Max Value: " << MAX_VALUE << std::endl;std::cout << "PI: " << PI << std::endl;std::cout << "App Name: " << APP_NAME << std::endl;return 0;
}
源文件 utils.cpp
#include <iostream>
#include "constants.h"void printConstants() {std::cout << "Max Value: " << MAX_VALUE << std::endl;std::cout << "PI: " << PI << std::endl;std::cout << "App Name: " << APP_NAME << std::endl;
}
编译和运行
- 编译所有源文件:
g++ main.cpp utils.cpp -o program
- 运行程序:
./program
输出结果
Max Value: 100
PI: 3.14159
App Name: MyApp
关键点解释
-
inline
关键字:- 在 C++17 中,
inline
关键字允许在头文件中定义变量,而不会导致链接错误。 - 每个包含该头文件的源文件都会共享同一个变量实例。
- 在 C++17 中,
-
constexpr
关键字:- 用于定义编译时常量,确保常量的值在编译时确定。
- 结合
inline
使用,可以定义跨文件共享的全局常量。
-
头文件保护:
- 使用
#ifndef
、#define
和#endif
防止头文件重复包含。
- 使用
优点
- 代码简洁:
- 全局常量只需在头文件中定义一次,所有源文件都可以直接使用。
- 避免重复定义:
- 使用
inline
关键字避免了传统全局变量在多个源文件中重复定义的问题。
- 使用
- 编译时常量:
- 使用
constexpr
定义的常量在编译时确定,提高了性能。
- 使用
注意事项
- C++17 及以上版本:
- 内联变量是 C++17 引入的特性,确保编译器支持 C++17 或更高版本。
- 避免滥用全局常量:
- 全局常量应仅用于真正需要跨文件共享的值,避免过度使用导致代码耦合性增加。
inline 的原理
链接器的作用
在 C++ 中,编译器和链接器共同工作:
编译器:将每个源文件编译成目标文件(.o 或 .obj)。
链接器:将所有目标文件合并成一个可执行文件,并解决符号引用(如变量和函数)。
传统全局变量的问题在于,如果多个源文件包含同一个头文件,并且头文件中定义了变量,链接器会发现多个相同的符号,导致 重复定义 错误。
inline 的机制
当使用 inline 关键字定义变量时,编译器会做以下事情:
标记符号为弱符号(weak symbol):
弱符号允许多个翻译单元定义相同的符号,而不会导致链接错误。
链接器会选择其中一个定义作为最终符号,忽略其他重复定义。
确保唯一性:
编译器会确保所有翻译单元共享同一个变量实例,而不是每个翻译单元都有自己的副本。
总结
通过使用 内联变量(inline variables),可以在 C++17 中轻松实现跨多个文件共享全局常量。这种方式既简洁又高效,避免了传统全局变量可能导致的链接错误,是现代 C++ 中推荐的做法。
相关文章:
内联变量(inline variables):在多个文件中共享全局常量
在 C17 中,引入了 内联变量(inline variables) 的概念,可以用于在多个文件中共享全局常量。内联变量允许在头文件中定义变量,而不会导致链接错误(如重复定义)。这种方式非常适合用于定义跨多个文…...

Jmeter进行http接口并发测试
目录: 1、Jmeter设置(1)设置请求并发数(2)设置请求地址以及参数(3)添加结果数 2、启动看结果 1、Jmeter设置 (1)设置请求并发数 (2)设置请求地址…...
力扣解题汇总_JAVA
文章目录 数学_简单13_罗马数字转整数66_ 加一9_回文数70_爬楼梯69_x的平方根509_斐波那契数列2235_两整数相加67_二进制求和415_字符串相加2413_最小偶倍数2469_温度转换704_二分查找(重点) 数组_简单1_两数之和88_合并两个有序数组 链表_简单21_合并两个有序链表203_移除链表…...
ubuntu下安装编译cmake,grpc与protobuf
文章目录 install cmakeinstall grpcinstall protobuf注 install cmake sudo apt-get install -y g make libssl-devcd third_party/cmake-3.17.2./configuresudo make && make installcmake --version install grpc $ sudo apt-get install -y build-essential auto…...

SQL Prompt 插件
SQL Prompt 插件 注:SQL Prompt插件提供智能代码补全、SQL格式化、代码自动提示和快捷输入等功能,非常方便,可以自行去尝试体会。 1、问题 SSMS(SQL Server Management Studio)是SQL Server自带的管理工具,…...

知识图谱抽取分析中,如何做好实体对齐?
在知识图谱抽取分析中,实体对齐是将不同知识图谱中的相同实体映射到同一表示空间的关键步骤。为了做好实体对齐,可以参考以下方法和策略: 基于表示学习的方法: 使用知识图谱嵌入技术,如TransE、GCN等,将实体…...

【Python通过UDP协议传输视频数据】(界面识别)
提示:界面识别项目 前言 随着网络通信技术的发展,视频数据的实时传输在各种场景中得到了广泛应用。UDP(User Datagram Protocol)作为一种无连接的协议,凭借其低延迟、高效率的特性,在实时性要求较高的视频…...

【伪随机数】关于排序算法自测如何生成随机数而引发的……
以 Random 开始 可能一开始,你只是写到了排序算法如何生成随机数 public static void main(String[] args) {Random random new Random();int[] nums new int[10];for (int i 0; i < nums.length; i) {nums[i] random.nextInt(100);}System.out.println(&q…...
核密度估计(Kernel Density Estimation, KDE)是一种非参数统计方法
一、核密度估计 核密度估计(Kernel Density Estimation, KDE)是一种非参数统计方法,用于估计随机变量的概率密度函数。它通过将每个数据点周围的核函数叠加,生成平滑的密度曲线。以下是其核心要点: 1. 基本概念 非参…...

【k8s面试题2025】2、练气初期
在练气初期,灵气还比较稀薄,只能勉强在体内运转几个周天。 文章目录 简述k8s静态pod为 Kubernetes 集群移除新节点:为 K8s 集群添加新节点Kubernetes 中 Pod 的调度流程 简述k8s静态pod 定义 静态Pod是一种特殊类型的Pod,它是由ku…...

栈溢出原理
文章目录 前言一、基本示例二、分析栈1. 先不考虑gets函数的栈情况2. 分析gets函数的栈区情况 三、利用栈1. 构造字符串2. 利用漏洞 前言 栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变。…...

Jmeter如何进行多服务器远程测试
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 JMeter是Apache软件基金会的开源项目,主要来做功能和性能测试,用Java编写。 我们一般都会用JMeter在本地进行测试,但是受到单…...
2.slf4j入口
文章目录 一、故事引入二、原理探究三、SLF4JServiceProvider四、总结 一、故事引入 故事要从下面这段代码说起 public class App {private static final Logger logger LoggerFactory.getLogger(App.class);public static void main( String[] args ) throws Exception {lo…...

初学stm32 --- CAN
目录 CAN介绍 CAN总线拓扑图 CAN总线特点 CAN应用场景 CAN物理层 CAN收发器芯片介绍 CAN协议层 数据帧介绍 CAN位时序介绍 数据同步过程 硬件同步 再同步 CAN总线仲裁 STM32 CAN控制器介绍 CAN控制器模式 CAN控制器模式 CAN控制器框图 发送处理 接收处理 接收过…...

软件测试—接口测试面试题及jmeter面试题
一,接口面试题 1.接口的作用 实现前后端的交互,实现数据的传输 2.什么是接口测试 接口测试就是对系统或组件之间的接口进行测试,主要是校验数据的交换、传递和控制管理过程,以及相互逻辑关系 3.接口测试必要性 1.可以发现很…...

图论的起点——七桥问题
普瑞格尔河从古堡哥尼斯堡市中心流过,河中有小岛两座,筑有7座古桥,哥尼斯堡人杰地灵,市民普遍爱好数学。1736年,该市一名市民向大数学家Euler提出如下的所谓“七桥问题”: 从家里出发,7座桥每桥…...
嵌入式开发通讯协议大全(在写中)
目录 modbus RTU通讯协议: pmbus通讯协议: modbus RTU通讯协议: 主要应用功能: 规范了软件变量,访问功能码,给不同工程师开发的不同产品有统一的通讯标准 帧结构简单,占用带宽少,…...
webpack 4 升级 webpack 5
升级至最新的 webpack 和 webpack-cli npm run build 报错, unknown option -p 解决方案: 改成 --mode production npm run build 报错 unknown option --hide-modules 解决方案:直接移除 npm run build 报错:TypeError: Cannot a…...
oneplus3t-lineageos-16.1编译-android9, oneplus3t-lineage-14编译-android7
oneplus3t-lineage-14编译-android7 1 清华linageos镜像 x lineage-14.1-20180223-nightly-oneplus3-signed.zip ntfs分区挂载为普通用户目录 , ext4分区挂载为普通用户目录 bfsu/lineageOS镜像 ts/lingeageOS镜像 oneplus3/lineage-build-simple-manual.md, manifest-p…...

HTML中最基本的东西
本文内容的标签,将是看懂HTML的最基本之基本 ,是跟您在写文章时候一样内容。一般想掌握极其容易,但是也要懂得如何使用,过目不忘,为手熟尔。才是我们学习的最终目的。其实边看边敲都行,或者是边看边复制粘贴…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...