C++ 的 Linkage
Linkage
- 链接
- 内部链接
- 外部链接
- 总结
- Reference
链接
在 C++ 代码运行之前,编译器和连接器的需要完成它们的工作。如果想要程序能够顺利地跑起来,我们需要了解 C++ 中的两个个至关重要的概念 translation unit (编译单元,简称 TU) 和 one definition rule (定义一次规则,下面简称 ODR) 。
所谓的 TU 就是一个 source file (源文件) 和 它所引用的 header files (头文件) 。而 linkage (链接) 可以理解为一个变量或者一个函数是否只作用于某个 TU 。
内部链接
而链接又分为 internal linkage (内部连接) 和 external linkage (外部链接) 。内部连接,顾名思义,如果一个变量是属于内部连接的话,那么它在每一个 TU 里面都是独一无二的。只要满足以下条件,对象的链接方式均为内部连接[^1]:
- const object (如
const int*
、const double
等等) - constexpr objects (如
constexpr char*
) - typedefs
- static objects in namespace scope (如全局
static int age
)
在 a.h 文件中声明并初始化 const int* iptr
,然后被包含到不同的 TU 中。我们不难发现每个独立的 TU 都有自己的一个 iptr
,它们互不干扰互不影响。
// a.h
const int* iptr = new int(111); //a.cpp
#include "a.h"
void scope_a()
{std::cout << *iptr << "\n";
}// b.h 为空文件
// b.cpp
#include "b.h"
#include "a.h"
void scope_b()
{*iptr = 222;std::cout << *iptr << "\n";
}// main.cpp
#include "a.h"
#include "b.h"
int main()
{*iptr = 333;std::cout << *iptr << "\n"; // 打印 333scope_a(); // 打印 111scope_b(); // 打印 222
}
外部链接
与内部链接不同的是,链接方式属于外部链接的变量,无论在多少个 TU 里,都是同一个对象。如果我们试图在 a.h 文件中声明并初始化一个变量 int num = 111
的话,程序会出错。因为这里的定义并不满足,上述内部链接的 4 个条件。
// a.h
int num = 111;
void scope_a();//a.cpp
#include "a.h"
void scope_a()
{std::cout << num << "\n";
}// b.cpp
#include "b.h"
#include "a.h"
void scope_b()
{std::cout << num << "\n";
}// main.cpp
#include "a.h"
#include "b.h"
int main()
{std::cout << num << "\n";scope_a();scope_b();
}
很遗憾,上面的代码发生了连接错误:
"int num" already defined in A.obj
"int num" already defined in A.obj
one or more multiply defined symbols found
num
的声明和定义是在 a.h 同时进行,所以出现这样的报错是正常的,因为违反了 ODR 。为了修正这样的错误,extern
关键字派上用场。值得注意的是,如果要使用 extern
去修饰一个变量的话,该变量的声明和定义必须在源文件内进行。
// a.h
void scope_a();//a.cpp
#include "a.h"
extern int num = -1;
void scope_a()
{std::cout << num << "\n";
}// b.cpp
#include "b.h"
#include "a.h"
extern int num;
void scope_b()
{num = 0;std::cout << num << "\n";
}// main.cpp
#include "a.h"
#include "b.h"
extern int num;
int main()
{num = 1;std::cout << num << "\n";scope_a();scope_b();std::cout << num << "\n";
}
输出结果:
1
1
0
0
总结
一般情况下,我们都会避免用全局变量。因为全局变量的使用不当,会给程序带来一定的风险。
Reference
^1 :https://docs.microsoft.com/en-us/cpp/cpp/program-and-linkage-cpp?view=vs-2019
C++ 的 Linkage相关推荐
- DX11 preprocessor Dynamic shader linkage
(参照例子DXSDK sample:DynamicShaderLinkage11) 一.preprocessor 实现shader静态分支的经典方法,代码示例如下 shader中(如果显卡不支持DX1 ...
- Keil5报错:error: more than one instance overload function “xx“ has C linkage
转自:https://blog.csdn.net/malloc_luo/article/details/104437926 用Keil编写C.C++混编程序碰到了这个问题 #ifdef __cplus ...
- 解决警告inconsistent dll linkage
今天用C++动态库导出一个类,导出头文件如下: #pragma once #ifdef DLLMSG_EXPORTS #define DLLMSG_API __declspec(dllexport) ...
- dbscan论文_论文分享 :Linkage Based Face Clustering via GCN
本文要解决的问题是人脸聚类,这类任务的目的是将一批无标记的人脸通过聚类使得自同一个人的人脸聚在一起.作者将这个问题转换为链路预测的问题,当两个人脸属于同一个人时,那么他们之间存在一条边.作者发现特征空 ...
- 凝聚式层次聚类 java_凝聚法层次聚类之ward linkage method
凝聚法分层聚类中有一堆方法可以用来算两点(pair)之间的距离:欧式,欧式平方,manhattan等,还有一堆方法可以算类(cluster)与类之间的距离,什么single-linkage.compl ...
- 电路理论与linkage Mapper的安装
Linkage Mapper 是一个综合MCR.电路理论.图论的工具,可以用于构建生态廊道(线状和面状).可利用电路理论,结合circuitscape插件 识别重要生态节点(踏脚石(又有夹点.垫脚 ...
- 层次聚类——linkage方法
最近在使用层次聚类时,简单了解了一下合并类簇时所使用的几种linkage方法,在这里作一下简单的总结. 1963年,Ward J H提出了使用离差平方(Error Sum of Square)和或者说 ...
- 【论文阅读】PAIRWISE LINKAGE FOR POINT CLOUD SEGMENTATION-ISPRS-luxiaohu
目录 PAIRWISE LINKAGE FOR POINT CLOUD SEGMENTATION 1. INTRODUCTION cluster segment Objectives and Moti ...
- 连锁定位(Linkage Mapping)与关联定位(Association Mapping)
本文主要介绍了育种领域早期(2001年以前)定位 QTL(quantitative trait loci,数量性状基因座)所使用的方法及分子标记.虽然随着分子标记技术的不断更新,定位方法中的许多问题已 ...
- # Linkage Mapper 版本及下载
# Linkage Mapper 版本及下载 Linkage Mapper 从2009年到现在更新了多个版本,不同版本搭配不同的ArcGIS版本使用,最新的ArcGIS 10.0-10.6版本使用 ...
最新文章
- 使用Jest测试JavaScript (入门篇)
- const成员函数、const类对象、mutable数据成员
- 使用事件和消息队列实现分布式事务
- 单交换机VLAN 配置和结果验证(51cto-o8)
- 前端学习(970):fastclick插件使用
- excel 科学计数法转换成文本完整显示_表格技巧—Excel里身份证号码显示不全的多种解决办法...
- 台式计算机有什么配置,目前台式电脑的主流配置有哪些?
- 渐变背景免费UI设计素材专辑,让设计显得魅力非凡
- 请千万不要在 JDK 7+ 中使用这个 JSON 包了!切记
- jstl中的日期格式化
- python数值分为3种类型_Python数值类型
- 2022年学习数据科学的18个网站
- 局域网计算机加密共享文件,怎么共享文件夹局域网(局域网共享加密)
- windows 7 旗舰版下,安装vs2010旗舰版终于成功!
- 领扣LintCode问题答案-5. 第k大元素
- 基于TI AM335X的工业网关参考设计分享
- VSC | vscode 常用快捷键
- 转:成为Java高级程序员需要掌握哪些?
- 发展5G通信,测试先行
- python --安装pylab
热门文章
- 成都专业计算机职称考试地点,2018年12月四川成都职称计算机考试报名通知
- 解决CentOS虚拟机开机黑屏卡死问题
- 在线教育7年探索史 | 详解
- 图文手把手教程--ESP32 OTA空中升级(阿里云物联网平台)
- FLIR Systems获得美国陆军士兵随身传感器项目价值3960万美元的“黑黄蜂”个人侦察系统合同
- 浅谈医疗信息化安全的防御体系
- bluestack模拟器测试APK,使用obb文件资源解压
- 《2022 FISCO BCOS产业应用白皮书》共编邀请,期待您的参与
- 获取最新的安全资讯与技术
- 第15届全国大学生知识竞赛场景实操 2022ciscn初赛 部分writeup