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

news2024/11/23 15:44:30

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++第十五弹---string基本介绍(一)

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】 目录 1、什么是STL 2、STL的版本 3、STL的六大组件 4、STL的重要性 5、如何学习STL 6、STL的缺陷 7、为什么学习string类 7.1、C语言中的字符串…

autodl常用工具命令

以下内容仅为当前认识,可能有不足之处,欢迎讨论! 文章目录 tar/zip命令镜像版本参考torch包全版本下载torch和cuda版本对应conda命令conda打包conda 环境重命名conda环境复制和转移conda环境删除 tar/zip命令 参考链接 文件目录打包&#x…

macU盘在电脑上读不出来 u盘mac读不出来怎么办 macu盘不能写入 Tuxera NTFS for Mac免费下载

对于Mac用户来说,使用U盘是很常见的操作,但有时候可能会遇到Mac电脑无法读取U盘的情况,这时候就需要使用一些特定的工具软件来帮助我们解决问题。本文就来告诉大家macU盘在电脑上读不出来是怎么回事,u盘mac读不出来怎么办。 一、m…

PTA题解 --- 静静的推荐(C语言)

今天是PTA题库解法讲解的第七天,今天我们要讲解静静的推荐,题目如下: 解题思路: 这个问题的核心在于如何在满足给定条件的情况下,最大化推荐学生的数量。首先,我们需要过滤出所有天梯赛成绩不低于175分的学…

3.2.k8s搭建-kubeadm

目录 一、虚拟机准备 二、所有节点环境准备 1.所有节点做hosts解析 2.所有节点重新命名 3.所有节点安装docker 4.所有节点为docker做linux内核转发 5.所有节点配置docker 6.所有节点关闭swap分区 7.所有节点验证网卡硬件编号是否冲突 8.所有节点配置允许iptables桥接…

Nginx配置文件修改结合内网穿透实现公网访问多个本地web站点

文章目录 1. 下载windows版Nginx2. 配置Nginx3. 测试局域网访问4. cpolar内网穿透5. 测试公网访问6. 配置固定二级子域名7. 测试访问公网固定二级子域名 1. 下载windows版Nginx 进入官方网站(http://nginx.org/en/download.html)下载windows版的nginx 下载好后解压进入nginx目…

水质监测站解析

TH-LSZ05水质监测站作为水资源保护和环境管理的重要工具,其功能和作用正日益受到人们的重视。随着科技的不断进步,水质监测站也在不断更新和完善,以适应不同场合和需求的监测任务。 首先,在技术创新方面,水质监测站正…

域控网络的创建

打进内网的方法 1.web服务器 域控创建 配置自己的ip winr:ncpa.cpl 然后属性将自己电脑的ip修改为静态ip 将DNS 修改为自己的ip 输入 winR 输入dcpromo 创建一个域 名为 cc.com 尝试去ping通 并将DNS 修改为自动 看看ping通的区别 在另一台电脑DNS修改为刚刚…

Android Studio 生成 keystore 签名文件及打包验证流程

一、创建keystore签名文件 1、在菜单栏中,依次点击 Build - Generate Signed Bundle/Apk...(生成签名) 2、选择 APK 选项,点击按钮 Next 到下一步 3、新建key store秘钥文件,点击按钮 Next 到下一步 4、按如下提示填写信息,点击按…

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第二套

华为海思校园招聘-芯片-数字 IC 方向 题目分享(有参考答案)——第二套(共九套,每套四十个选择题) 部分题目分享,完整版获取(WX:didadidadidida313,加我备注:CSDN huawei…

[开源] 基于transformer的时间序列预测模型python代码

分享一下基于transformer的时间序列预测模型python代码,给大家,记得点赞哦 #!/usr/bin/env python # coding: 帅帅的笔者import torch import torch.nn as nn import numpy as np import pandas as pd import time import math import matplotlib.pyplo…

UI自动化测试重点思考(下)--装饰器/生成器/夹具的使用/描述符的作用/ddt驱动/多线程

UI自动化测试重点思考--装饰器 装饰器装饰器定义装饰器代码示例装饰器的执行如何将装饰器融合到pytest框架里面 生成器创建生成器生成器的定义如何将生成器融合到pytest框架里面 fixture(夹具)使用pytest fixture 中 scope 参数的详细解释 描述符的总结描…

大话设计模式——16.命令模式(Command Pattern)

简介 请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的对象进行执行。命令模式是一种特殊的策略模式,体现多个策略执行的问题,而不是选择的问题 UML图 应用场景 界面选择、键盘、按钮、事件操作都类似命令模式 …

桌面图标不见了怎么恢复?3个轻松恢复方法请记好!

“我今天刚刚打开电脑就发现我电脑桌面的图标不见了,这是为什么呢?有什么方法可以帮助我快速找回这些图标吗?非常感谢!” 在日常使用电脑的过程中,有时我们会突然发现桌面上的图标不见了,这往往会让人感到困…

断点续传-视频文件的分块和合并

目录 一,前言 二,断点续传 三,断点续传流程: 四,java代码测试分块和合并 视频文件分块: 视频文件合并: 五,应用(简单了解) 一,前言 通常视频文件都比较大,项目中…

读博做FPGA上的AI加速能不能搞啊?

从企业的角度来看,选择在FPGA上进行AI加速仍然有其一定的优势和适用场景,但也有一些挑战需要考虑。我这里有一套嵌入式入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习嵌入式,不妨点个关注,给…

人工智能_大模型023_AssistantsAPI_01_OpenAI助手的创建_API的调用_生命周期管理_对话服务创建---人工智能工作笔记0159

先来说一下一些问题: 尽量不要微调,很麻烦,而且效果需要自己不断的去测试. 如果文档中有图表,大量的图片去分析就不合适了. 是否用RAG搜索,这个可以这样来弄,首先去es库去搜能直接找到答案可以就不用去RAG检索了,也可以设置一个分,如果低于60分,那么就可以去进行RAG检索 微…

网络通信流程

建立完tcp请求再发起http请求 开启系统代理之后,以clash verge为例 127.0.0.1:7897,假设hci.baidu.com的IP为153.37.235.50 发起对hci.baidu.com的HTTP请求,由于开启了系统代理不进行DNS解析,浏览器调用socket()获得一个socket&a…

平面图设计利器:推荐4款好用软件助你完成任务!

在移动应用程序或网页UI设计项目中,平面图软件是必不可少的。市场上的平面图绘制软件层出不穷。UI设计师有必要了解如何找到一款简单易用、专业的平面图绘制软件。本文将分享四款流行的平面图绘制软件,每一款都具有不同的设计功能、易学性和性价比。 即…

基于单片机数码管20V电压表仿真设计

**单片机设计介绍,基于单片机数码管20V电压表仿真设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机数码管20V电压表仿真设计的主要目的是通过单片机和数码管显示电路实现一个能够测量0到20V直流电压的电…