c++ 的 multiple definition of `XXX‘

2023-10-29

一、为什么会有多重定义问题?

  • 声明 :指出存储类型,并给出存储单元指定名称
  • 定义 : 分配内存空间,还可为变量指定初始值(对于变量,在内存中开辟空间来保存数据;对于函数,会生成代码,占据一定内存)
  • extern 关键字: 如果想声明一个变量而非定义它,就在变量名前加extern 关键字,而且不要显示初始化变量.(extern 语句如果包含了初始值,就变成定义了)
  • 在函数被调用之前必须先有函数原型(函数声明),函数定义可以放在调用函数的后面
extern double i ; //声明i而非定义i
int i; //声明并定义i

变量能且只能被定义一次,但可以被多次声明

  • 因为c++语言支持分离式编译,允许程序分割为若干个文件,每个文件可独立编译。如果多个文件共享一个变量,就必须将声明和定义分离,且变量的定义必须出现在且只能出现在一个文件中,否则就出现了重复定义问题。

原文链接:https://blog.csdn.net/mantis_1984/article/details/53571758

  • 函数声明和定义也是如此。如果函数定义在a.h,且a.h 被多个文件包含,那么就会报重定义错误

三种可以把定义放在头文件的

  • 值在编译时就已知的const 变量的定义
  • 类的定义可以放在头文件
  • inline函数(内联函数的声明和定义需要在同一文件,否则无法通过编译。编译器需要将内联函数插入到调用位置)
  • 模板函数,编译时需要根据函数模板实例化对应函数

二、 一些错误情景

1、头文件忘记加条件编译

#pragma once
或者
#ifndef HEAD_H
#define HEAD_H
...
#endif

这里补充一下,加条件编译只是防止同一个cpp文件包含同一个头文件多次,在独立编译时生成对应的符号表。可能就会发生两个cpp文件都有同一个全局变量的定义,到链接时双方一交流,发现重复,就报错了。

2、类的静态变量在头文件定义

比如下面的A:count在a.h定义,若a.h被多个文件包含,就会重定义
a.h

#pragma once
#include <iostream>
using namespace std;

class A{
public :
    static int count ; 
    void inc();
};
int A::count = 0;

解决办法:

把a.h里对静态变量的定义放在cpp文件中,.h不要定义
a.cpp 实现

#include "a.h"
int A::count = 0;//定义
void A::inc(){
    count++;
}

3、全局变量在.h文件定义

原理同2差不多,解决办法是在a.cpp定义,然后a.h文件 extern 声明,然后其他需要使用全局变量的.c文件中包含a.h文件即可.

//a.h
extern int aa;

//a.cpp
int aa = 10;

之前还看到过一个解决办法时加static关键字,后来又查了下,在.h 文件

//a.h
static int aa = 3;

相当于把aa的作用域局限于定义它的源文件中,其他源文件不能访问。换句话说,如果b.cpp 和d.cpp都包含了a.h, 相当于每一个cpp文件定义了一个新的单独的变量aa,彼此空间独立,互不干扰,并不是真正的空间变量。

4、待补充

三、参考链接

https://zhuanlan.zhihu.com/p/74528787
https://zhuanlan.zhihu.com/p/38588925
https://blog.csdn.net/mantis_1984/article/details/53571758

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++ 的 multiple definition of `XXX‘ 的相关文章

随机推荐

  • 【多字典公共键】快速找到多个字典的公共键及非公共键

    前言 在进行一个项目过程中遇到一个多个URL参数对比与分析的问题 所以就有了这个博客 单纯的了解找到多个字典的公共键的问题 可以移步到 python进阶 python进阶技巧 找到2 5 快速找到多个字典的公共键 想看实操 不妨浏览一下下面
  • keil关于use MicroLIB 和半主机模式的总结

    半主机是这么一种机制 它使得在ARM目标上跑的代码 如果主机电脑运行了调试器 那么该代码可以使用该主机电脑的输入输出设备 这点非常重要 因为开发初期 可能开发者根本不知道该 ARM 器件上有什么输入输出设备 而半主基机制使得你不用知道ARM
  • 虚拟机连接本地数据库

    我们在运行虚拟机上面的项目时 可能要用到本机的数据库 在使用过程中会遇到数据库拒绝访问的情况 这是因为在安装本地数据库时没有启动远程连接 使用两种方法来解决这种问题 一 使用命令行模式 第一步 先切换到MySQL的安装路径下面的bin目录
  • 百分率的sql

    百分比的sql语句 方式一的百分比的sql 说明 这条sql是在一张表里面进行查询 将不同的级别的工程师的百分率查询出来 第一个sql select tmp job grade tmp tcount tmp1 t1count from se
  • 基于单片机的数字频率计设计

    数字频率计概述 数字频率计是计算机 通讯设备 音频视频等科研生产领域不可缺少的测量仪器 它是一种用十进制数字显示被测信号频率的数字测量仪器 它的基本功能是测量正弦信号 方波信号及其他各种单位时间内变化的物理量 在进行模拟 数字电路的设计 安
  • 【力扣】205.同构字符串

    同构字符串 同构字符串 1 题目描述 2 示例 3 代码 方式1 方式2 5 编译结果 同构字符串 1 题目描述 给定两个字符串 s 和 t 判断它们是否是同构的 如果 s 中的字符可以按某种映射关系替换得到 t 那么这两个字符串是同构的
  • 【蓝桥杯Python】2023.2.3-寻找2020

    题目描述 本题为填空题 只需要算出结果后 在代码中使用输出语句将所填结果输出即可 小蓝有一个数字矩阵 里面只包含数字 00 和 22 小蓝很喜欢 20202020 他想找 到这个数字矩阵中有多少个 20202020 小蓝只关注三种构成 20
  • 2023华为OD机试真题【施肥问题】

    题目描述 思路题解 首先需要计算每个果园的施肥时间 即果园面积除以施肥机能效 然后找到最小的施肥机能效 保证施肥任务能在规定时间内完成 如果施肥天数小于果园数量 则无法完成施肥任务 返回 1 如果施肥天数等于果园数量 则直接返回最大果园面积
  • 编译原理第七章笔记 -- 中间代码生成

    本文中内容整理西安交通大学软件学院吴晓军老师的ppt中 仅供学习使用 请勿转载或他用 参考教材 程序设计语言 编译原理 第3版 陈火旺等 国防工业出版社 这一章分数在35左右 两个大题 数组的引用四元式生成 控制语句当中布尔表达式的翻译 考
  • 运维必学

    欢迎关注 全栈工程师修炼指南 设为 星标 每天带你 基础入门 到 进阶实践 再到 放弃学习 专注 企业运维实践 网络安全 系统运维 应用开发 物联网实战 全栈文章 等知识分享 花开堪折直须折 莫待无花空折枝 作者 lt 安全开发运维 gt
  • VS2012编译安装VTK-5.10.1(支持Python)

    1 源码下载 到参考资料 1 下载vtk 5 10 1 zip和vtkdata 5 10 1 zip 2 源码解压 这里以D 盘为例进行说明 在D 盘中创建一个目录VTK 然后在其中创建4个目录 source build data和inst
  • mysql explain详解

    转自 http www blogjava net persister archive 2008 10 27 236813 html 在 explain的帮助下 您就知道什么时候该给表添加索引 以使用索引来查找记录从而让select 运行更快
  • Nginx反向代理与负载均衡

    文章目录 一 网关 代理与反向代理的关系 二 反向代理在系统架构中的应用场景 三 Nginx反向代理配置 1 不重定向配置 2 重定向配置 四 基于反向代理的负载均衡器 不支持https 五 负载均衡介绍 1 负载均衡策略 2 负载均衡调度
  • 三个java超级变态逻辑循环编程题

    1 有一根27厘米的细木杆 在第3厘米 7厘米 11厘米 17厘米 23厘米这五个位置上各有一只蚂蚁 木杆很细 不能同时通过一只蚂蚁 开始时 蚂蚁的头朝左还是朝右是任意的 它们只会朝前走或调头 但不会后退 当任意两只蚂蚁碰头时 两只蚂蚁会同
  • 【4】测试用例设计-判定表法

    判定表适用于有几个原因 导致几个结果的情况 实际测试中 如果输入条件较多 再加上各种输入与输出之间相互的作用关系 画出的因果图会比较复杂 容易使人混乱 为了避免这种情况 人们往往使用决策表法代替因果图法 决策表也称为 判定表 其实质就是一种
  • 各大公司薪资

    联合利华 MKT 9500 3000元安家费 普通职位 8KX12 联合利华销售代表 底薪加提成 总体一般 一般能拿到5K以上 宝洁 本8600 硕9700 博10500发14个月 11年数据 欧莱雅 MKT 6 6K X 13 11年数据
  • ajax工作原理 网页从输入url到呈现过程(TCP ,渲染引擎) 头像上传 下拉加载 节流 防抖 常见状态码

    Ajax工作原理 1 http网络传输协议 规定 前后端交互的 数据传输格式 协议 规定 前后端交互的数据传输格式 2 http协议组成两个部分 2 1前端 必须发送 请求报文格式 2 2后端 必须响应 响应报文格式 3 请求报文格式组成
  • VueX是什么?好处?何时使用?

    VueX相关 1 VueX是什么 2 使用VueX统一管理状态的好处 3 什么样的数据适合存储到Vuex中 1 VueX是什么 VueX是实现组件全局状态 数据 管理的一种机制 可以方便的实现组件之间数据的共享 如果没有VueX实现数据间的
  • 点云配准(四) Sparse Point Registration 算法浅析

    Sparse Point Registration SPR 是一篇2017年的点云配准算法 该算法的主要目的是对稀疏点云进行配准 并且取得了不错的成果和突破 本文一方面是对SPR配准算法模型进行了简单的原理解析以及附加代码实现 另一方面是对
  • c++ 的 multiple definition of `XXX‘

    文章目录 一 为什么会有多重定义问题 二 一些错误情景 1 头文件忘记加条件编译 2 类的静态变量在头文件定义 3 全局变量在 h文件定义 4 待补充 三 参考链接 一 为什么会有多重定义问题 声明 指出存储类型 并给出存储单元指定名称 定