error:LNK2005 已经在*.obj中定义 的原因分析及对策

LNK2005是一个重复定义错误,造成LNK2005主要有以下几种情况:

目录

全局变量的重复定义

情况A:全局变量在.cpp文件中的多次声明

情况B:变量名重复

头文件的包含重复

解决方案

#ifndef标识符宏定义

pragma once预编译

头文件中的重定义

问题出现案例

案例报错原因

解决方案

《C++Primer》第四版中变量&声明

程序设计风格

总结

使用三方库的问题

解决方案

已知正确顺序,忽略错误库

不求甚解,疯狂尝试,只为成功

不求代价,只为成功编译运行


全局变量的重复定义

全局变量可能存在两种情况:

情况A:全局变量在.cpp文件中的多次声明

我们首先在一个cpp用到了一个全局变量a(10),会定义如下:

int a = 10;

在其他的cpp文件中继续使用该变量只需要声明:

extern int a;

如果我们需要在另一个cpp文件中使用int a,那么就会产生LNK2005错误。

此时,在其他cpp文件声明的时候不要给变量赋值(赋值就成了定义),否则还是会有LNK2005的错误。

extern int a = 10;

根据C++标准,一个变量是声明,必须同时满足两个条件,否则就是定义:

  • 声明必须使用extern关键字
  • 不能给变量赋初值

所以,下面的是声明:

extern int a;

下面的是定义:

int a;  
int a = 0;  
extern int a =0; 

情况B:变量名重复

对于粗心的我来说,总是在需要使用变量的cpp文件中随意定义一个全局变量 int a =0;,在下一个文件中又无意用到了一个新的a “int a = 0”,这造成了变量名重复的LNK2005错误。

头文件的包含重复

一般,头文件含有变量、函数、类的定义。

重复引用头文件,那么就会产生LNK2005错误。

解决方案

#ifndef标识符宏定义

在需要包含的头文件中做类似的处理:

#ifndef MY_H_FILE
//如果没有定义这个宏
#define MY_H_FILE
//定义这个宏
//...code...头文件主体内容
//...code...
endif

pragma once预编译

上面是使用宏来做的,也可以使用预编译来做,在头文件中加入:

#pragma once
//...code...头文件主体

头文件中的重定义

问题出现案例

我经常忽略的一个细节,举例说明:

在头文件中声明了一个简单的类(注意里面的int getV()):

class Cube
{
public:
	Cube();
	~Cube();
	void setA(int a)
	{
		m_a = a;
	};
	void setB(int b)
	{
		m_a = b;
	};
	void setC(int c)
	{
		m_a = c;
	};
	
	int getV();//声明了getV().想要在外部单独定义
	
private:
	int m_a;
	int m_b;
	int m_c;
	int m_v;

};

紧接着,在类这个结构体下面定义int getV():

 int Cube::getV()
{
	m_v = m_a * m_b * m_c;
	return m_v;
};

案例运行结果:

案例报错原因

由于Cube::的原因,编辑器又内联了一次Cube类,造成了重定义。

解决方案

  1. 像void setC()一样,在类结构体的内联一起定义。
  2. 在实际的项目开发中,通常将声明和定义分开。将定义写到头文件对应的.cpp中。

注意:

《C++Primer》第四版中变量&声明

《C++Primer》第四版中是这么说的:

  • 变量定义:用于为变量分配存储空间,还可为变量指定初始值。程序中,变量有且仅有一个定义。
  • 变量声明:用于像程序表明变量的类型和名字。
  • 定义也是声明:当定义变量时,我们声明了它的类型和名字。
  • extern关键字:通过使用extern关键字声明变量名而不定义它。

程序设计风格

  • 不要把变量定义放在.h文件,这样容易导致重复定义错误。
  • 尽量使用static关键字把变量定义限制于该源文件的作用域,除非变量被设计成全局的。
  • 可以在头文件中声明一个变量,在用的时候包含这个头文件就声明了这个变量。

总结

  1. 变量在使用前就要被定义或声明;
  2. 一个程序中,变量只能定义一次,却可以声明很多次。
  3. 定义分配存储空间,而声明不会。

使用三方库的问题

这种情况主要是C运行期函数库MFC的库冲突造成的。

微软和C有两种C运行期函数库,一种是普通的函数库:LIBC.LIB,不支持多线程。另外一种是支持多线程的:msvcrt.lib。如果一个工程里,这两种函数库混合使用,可能会引起这个错误,一般情况下它需要MFC的库先于C运行期函数库被链接,因此建议使用支持多线程的msvcrt.lib。

所以在使用第三方的库之前首先要知道它链接的是什么库,否则就可能造成LNK2005错误。

可以选择VC菜单Project->Settings->Link页,然后在Project Options的Edit栏中输入/verbose:lib,这样就可以在编译链接程序过程中在输出窗口看到链接的顺序了。


解决方案

已知正确顺序,忽略错误库

选择VC菜单Project->Settings->Link->Catagory选择Input,再在Ignore libraries 的Edit栏中填入你需要忽略的库,如:Nafxcwd.lib;Libcmtd.lib。然后在Object/library Modules的Edit栏中填入正确的库的顺序,这里需要你能确定什么是正确的顺序

不求甚解,疯狂尝试,只为成功

选择VC菜单Project->Settings->C/C++页,Catagory选择Code Generation后再在User Runtime libraray中选择MultiThread DLL等其他库,逐一尝试。

不求代价,只为成功编译运行

使用代码执行命令强制执行/force:multiple

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/528249.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用yml文件配置python日志

新建一个logging.yml文件,内容如下: logging库提供了多个组件:Logger、Handler、Filter、Formatter: Logger 对象提供应用程序可直接使用的接口,供应用代码使用; Handler 发送日志到适当的目的地&#xff…

PMC管理中落实生产作业计划的思路与方法

在快节奏的现代商业环境中,PMC(生产及物料控制)管理对于确保企业生产流程的高效运转至关重要。生产作业计划的落实不仅关乎企业的生产效率和成本控制,更是企业竞争力的重要体现。那么,PMC管理中如何有效落实生产作业计…

上传应用程序到苹果应用商店的工具和要点

引言 在今天的移动应用市场中,将应用程序上传到苹果应用商店(App Store)是许多开发者的首要任务之一。然而,不同操作系统下的开发者可能需要使用不同的工具和遵循不同的要求来完成这一任务。本文将介绍在 macOS、Windows 和 Linu…

【C语言】:字符函数和字符串函数

这里写目录标题 1、strlen的使用和模拟实现2、strcpy的使用和模拟3、strcat 的使用和模拟实现4、strcmp 的使用和模拟实现5、strncpy 函数的使用6、strncat 函数的使用7、strncmp函数的使用8、strstr 的使用和模拟实现9、strtok 函数的使用10、strerror 函数的使用11、字符分类…

独家原创 | SCI 1区 高创新轴承故障诊断模型!

往期精彩内容: Python-凯斯西储大学(CWRU)轴承数据解读与分类处理 Python轴承故障诊断 (一)短时傅里叶变换STFT Python轴承故障诊断 (二)连续小波变换CWT_pyts 小波变换 故障-CSDN博客 Python轴承故障诊断 (三)经验模态分解EMD_轴承诊断 …

MySQL数据库 数据库基本操作(四):表的增删查改(下)

1. 联合查询 注:联合查询是面试中的重点,只要考到sql,大多数情况下都考的是联合查询,而且联合查询也是我们学习中的难点. 1.1 笛卡尔积 在实际开发中,数据往往来自不同的表,所以要多表联合查询.多表查询是对多张表的数据笛卡尔积. 它们是两张表的各行数据通过全排列得到的. …

摩尔信使MThings之数据网关:Modbus转MQTT

由于现场设备和物联网云平台采用了不同的通信协议,而为了实现它们之间的互操作性和数据交换,需要进行协议转换。 MQTT作为一种轻量级的、基于发布/订阅模式的通信协议,适用于连接分布式设备和传感器网络,而MODBUS协议则常用于工业…

ISG立式管道离心泵(管道增压泵)

一、设计特征 ISG立式管道离心泵是一种高效的水泵,它采用立式单级或多级离心泵的设计,使得电机轴与泵轴直接连接,减少了传输损失。该泵的主要部件包括电机、泵体、叶轮、轴封及泵盖等。与传统卧式泵相比,ISG泵占地面积小&#xff…

像用户一样测试:别掉链子

“掉链子”是一句俗语,比喻在关键时刻出故障,或者重要的事情本该做好却没做好。 “掉链子”的说法来自于自行车:在骑行过程中,链条通过链轮传送,带动车轮滚滚向前。当链条从链轮上脱落,就无法进行传动&…

k8s部署efk

环境简介: kubernetes: v1.22.2 helm: v3.12.0 elasticsearch: 8.8.0 chart包:19.10.0 fluentd: 1.16.2 chart包: 5.9.4 kibana: 8.2.2 chart包:10.1.9 整体架构图: 一、Elasticsearch安装…

跨境电商选品思路:12个方法和爆品法则(完结篇)

不管你是做亚马逊、速卖通、Shopee 、Lazada、美客多、eBay、SHEIN、Temu、Tiktok、shopify等跨境电商平台的卖家,选品思路一定要清楚,选到好品才是成为爆品的基础。店雷达继续给各位跨境商家分享12个大数据选品场景思路,错过其他选品场景思路…

建设智慧公厕有什么好处?@光明源,都有哪些功能?

在城市化进程不断加快的今天,智慧公厕作为城市基础设施的重要组成部分,正逐渐受到各地政府和管理者的重视。那么,建设智慧公厕到底有哪些好处?它们又都涉及哪些功能呢?让我们一起来探讨一下。 首先,建设智…

初学python记录:力扣1600. 王位继承顺序

题目: 一个王国里住着国王、他的孩子们、他的孙子们等等。每一个时间点,这个家庭里有人出生也有人死亡。 这个王国有一个明确规定的王位继承顺序,第一继承人总是国王自己。我们定义递归函数 Successor(x, curOrder) ,给定一个人…

基于SpringBoot+Vue+Mysql的图书管理系统

博主介绍: 大家好,本人精通Java、Python、C#、C、C编程语言,同时也熟练掌握微信小程序、Php和Android等技术,能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验,能够为学生提供各类…

[leetcode]只出现一次的数字Ⅲ

题目: 给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。 你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。 示例 1&…

Tiktok矩阵系统是什么?——Tiktok矩阵系统的优势、功能、及应用场景的介绍

摘要 Tiktok作为全球现象级的短视频平台,其发展前景日益明朗。 Tiktok全世界有多少用户? TikTok作为全球性的社交媒体平台,其用户数量一直在持续增长。根据最新的数据,预计到2024年,TikTok的用户数量将达到数十亿,覆盖全球范围内的各个年龄段和地区。具体来说,根据Ti…

总结SQL相对常用的几个字符函数

目录 字符的截取 substr() trim()、ltrim()、rtrim() 字符串的拼接 ||、 字符的大小写转换 upper(column_name):大写 lower(column_name):小写 字符替换 replace() 搜索字符 instr(column_name, substring_to_find,start,n_appearence) charindex(substring_to_fi…

HarmonyOS4.0 ArkUI构建布局

一、线性布局 属性说明: justifyContent:设置子元素在主轴方向的对齐方式 参数:FlexAlign枚举 alignItems:设置子元素在交叉轴方向的对齐方式 参数: Row容器使用VerticalAlign枚举Column容器使用HorizontalAlign枚举 …

k8s的ca以及相关证书签发流程

k8s的ca以及相关证书签发流程 1. kube-apiserver相关证书说明2. 生成CA凭证1.1. 生成CA私钥1.2. 生成CA证书 2. 生成kube-apiserver凭证2.1. 生成kube-apiserver私钥2.2. 生成kube-apiserver证书请求2.3. 生成kube-apiserver证书 3. 疑问和思考4. 参考文档 对于网站类的应用&am…

springboot 整合 mybatis(配置版)

代码及配置整合 创建实体类,与数据库对应 创建 mapper、service 和 controller @AutowiredUserService userService;@ResponseBody@GetMapping("/user")public com.vazquez.bootstudy.model.User getById(@RequestParam("id") Long id) {return userServ…