由于在多个 cpp 中包含相同标头而导致重复的多个定义错误

2023-12-10

因此,无论我做什么,我似乎都无法避免 Dev C++ 抛出大量多重定义错误,因为我在同一项目的多个源代码文件中包含相同的头文件。我强烈希望避免将所有源代码转储到一个文件中,并且只包含一次标头,因为这将使我的文件非常长且难以管理。

本质上,这是发生的事情:

#ifndef _myheader_h
#define _myheader_h

typedef struct MYSTRUCT{
int blah;
int blah2; } MYSTRUCT;

MYSTRUCT Job_Grunt;
MYSTRUCT *Grunt = &Job_Grunt;
MYSTRUCT Job_Uruk;
MYSTRUCT *Uruk = &Job_Grunt;

int Other_data[100];

void load_jobs();

#endif

示例 Cpp 文件(它们几乎都看起来像这样):

#include "myheader.h"

void load_jobs(){

Grunt->blah = 1;
Grunt->blah2 = 14;

Uruk->blah = 2;
Uruk->blah2 = 15;

return; }

请记住,我有大约 5 个 cpp 文件,其中包含这个头文件,每个文件都处理头文件中找到的不同类型的结构。在此示例中,只有一个结构体包含几个成员,而实际头文件中大约有 4-6 个不同的结构体,其中包含更多成员。我包含的所有文件都遵循与您在此示例中看到的相同的公式。

现在我明白标头防护只会阻止每个单独的 cpp 文件多次包含标头文件。似乎发生的情况是,当编译器在每个 cpp 开头读取包含时,它会重新定义头文件,这导致它吐出以下行:

Multiple Definition of Uruk, first defined here  
Multiple Definition of Job_Uruk, first defined here  
Multiple Definition of Grunt, first defined here  
Multiple Definition of Job_Grunt, first defined here  
Multiple Definition of Other_data, first defined here

我将在项目中的几乎每个 cpp 文件(包括标头)中看到一组这样的内容。我尝试将结构和结构变量的定义移至 cpp 文件,但其他 cpp 文件无法看到它们或使用它们,这非常重要,因为我需要项目中的所有文件都能够工作与这些结构。

但这个问题最令人困惑的部分需要更多解释:

我在这个项目中设置这些多个文件的方式与我正在使用的 John S. Harbour 的《All In One Game Programming》一书相同。当我为书中的示例项目创建文件时,我遇到了完全相同的问题,该文件要求同一项目中的多个 cpp 包含一个标头。

我可以把它们从书中逐字逐句地打出来,我的意思是逐字逐句......
我会收到项目中每个 cpp 的一系列 MD 错误。

如果我从本书附带的 CD 加载示例项目,它会毫无问题地编译和运行,尽管文件本身以及项目选项从外观上看与我创建的文件完全相同。

如果我创建自己的项目文件,并简单地从 CD 添加示例项目的源文件和头文件,这也将编译并运行,尽管我发现这些文件和我的项目没有任何区别。

然后,我尝试制作自己的项目文件,然后创建空白源文件和头文件并将它们添加到其中,然后通过从它们对应的 CD 上的文件复制并粘贴其内容来填充它们(相同那些曾经有效的)。 果然,我得到了同样的结果……一行又一行的 MD 错误消息。

我完全困惑了。我已经多次重复了所有这些方法,并且确信我没有错误输入或错误复制代码。预制文件本身似乎有一些东西;一些配置设置或其他我完全丢失的东西......这将导致它们正确编译,而我自己制作的文件则不会。


由于您在头文件中声明这些变量,并将头文件包含在每个 C++ 文件中,因此每个 C++ 文件都有其自己的副本。

解决这个问题的通常方法是not声明头文件中的任何变量。相反,在单个 C++ 文件中声明它们,并将它们声明为extern在您可能需要它们的所有其他文件中。

我之前处理过这个问题的另一种方法,有些人可能会认为不愉快......在头文件中声明它们,如下所示:

#ifdef MAINFILE
    #define EXTERN
#else
    #define EXTERN extern
#endif

EXTERN MYSTRUCT Job_Grunt;
EXTERN MYSTRUCT *Grunt = &Job_Grunt;
EXTERN MYSTRUCT Job_Uruk;
EXTERN MYSTRUCT *Uruk = &Job_Uruk;

然后,在one您的 C++ 文件中,添加...

#define MAINFILE

...在你之前#include线。这将处理所有事情,并且(在我个人看来)比必须重新声明每个文件中的所有变量要好得多。

当然,real解决方案是根本不使用全局变量,但是当您刚刚开始时,这很难实现。

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

由于在多个 cpp 中包含相同标头而导致重复的多个定义错误 的相关文章

  • 如何检查图像对象与资源中的图像对象是否相同?

    所以我试图创建一个简单的程序 只需在单击图片框中更改图片即可 我目前只使用两张图片 所以我的图片框单击事件函数的代码 看起来像这样 private void pictureBox1 Click object sender EventArgs
  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • pthread_cond_timedwait() 和 pthread_cond_broadcast() 解释

    因此 我在堆栈溢出和其他资源上进行了大量搜索 但我无法理解有关上述函数的一些内容 具体来说 1 当pthread cond timedwait 因为定时器值用完而返回时 它如何自动重新获取互斥锁 互斥锁可能被锁定在其他地方 例如 在生产者
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • 使用 System.Text.Json 即时格式化 JSON 流

    我有一个未缩进的 Json 字符串 例如 hash 123 id 456 我想缩进字符串并将其序列化为 JSON 文件 天真地 我可以使用缩进字符串Newtonsoft如下 using Newtonsoft Json Linq JToken
  • 如何将图像路径保存到Live Tile的WP8本地文件夹

    我正在更新我的 Windows Phone 应用程序以使用新的 WP8 文件存储 API 本地文件夹 而不是 WP7 API 隔离存储文件 旧的工作方法 这是我如何成功地将图像保存到 共享 ShellContent文件夹使用隔离存储文件方法
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 需要哪个版本的 Visual C++ 运行时库?

    microsoft 的最新 vcredist 2010 版 是否包含以前的版本 2008 SP1 和 2005 SP1 还是我需要安装全部 3 个版本 谢谢 你需要所有这些
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • 如何使用 std::string 将所有出现的一个字符替换为两个字符?

    有没有一种简单的方法来替换所有出现的 in a std string with 转义 a 中的所有斜杠std string 完成此操作的最简单方法可能是boost字符串算法库 http www boost org doc libs 1 46
  • ASP.NET MVC 6 (ASP.NET 5) 中的 Application_PreSendRequestHeaders 和 Application_BeginRequest

    如何在 ASP NET 5 MVC6 中使用这些方法 在 MVC5 中 我在 Global asax 中使用了它 现在呢 也许是入门班 protected void Application PreSendRequestHeaders obj

随机推荐

  • JavaFX TextField Array 文本值的最大长度

    我正在开发一个 JavaFX 项目 但在使用 TextField 控件时遇到问题 我想将用户在每个 TextField 中输入的字符限制为 1 个 如果您将单个文本字段与侦听器一起使用 我找到了一个解决方案 public static vo
  • onmouseout 时如何关闭组合框?

    鼠标移出时如何关闭组合框
  • NSURLProtocol registerClass 适用于 iOS 模拟器,但不适用于实际设备

    我正在打电话 NSURLProtocol registerClass 使用自定义协议 Chromium Cronet 播放视频时AVPlayer 注册完成于here 它在 iOS 模拟器 Xcode 11 3 上运行良好 但在实际设备 iP
  • 如何让 Zend Route 根据域名使用不同的模块

    我想设置多个域名来使用同一个框架 但我似乎无法让 zend 的路由器屈服于我的意愿 有很多使用子域的示例 但尝试使它们适用于整个域似乎并不像我期望的那样有效 这是我最接近的 但它似乎不起作用 resources router routes
  • htaccess 用于将非 www 重定向到 www,同时保留 http 和 https

    我的网站刚刚获得 EV SSL 证书 过去 我使用 htaccess 将非 www 请求重定向到 www 并且效果很好 但现在 如果我请求 https 页面 我最终会 通过 htaccess 重定向 得到 http 版本 我需要 htacc
  • 是否可以将 Cocoa Touch 手势识别器与图层/CALayer 对象一起使用?

    是否可以使用带有图层的手势识别器 假设我想向视图添加多个子图层并实现拖放以及点击单个元素 有可能吗 最好的模式是什么 您可以尝试将手势识别器添加到您的UIView然后打电话 CALayer hitTest CGPoint thePoint
  • Excel 2013 的 TextJoin UDF

    我正在尝试使用 TextJoin 的 UDF 版本 因为我使用的是 Excel 2013 但此函数无法正确返回准确的数据 我在 Excel 中的数据集如下所示 saleID Item 5 PRE2323 6 Pre2323223 6 OX1
  • 在 Jenkins 中获取负载参数

    我是詹金斯的新手 我跟着这个help实现 Jenkins Github 和 Webhook 但是 我陷入了这个问题 我想获取 Jenkins 中的有效负载参数 以检查有效负载 json 中的更改 操作等信息 我写了一些脚本来测试 ACTIO
  • 以编程方式合并两个音频片段

    我有两个不同音频剪辑的两个样本数组 如果我只是以编程方式将它们添加在一起 这是否相当于在音频编辑套件中将一个轨道叠加在另一个轨道上 就像如果我有一个贝斯的音频片段和另一个鼓的音频片段 我希望它们一起演奏 我可能会做这样的事情 for int
  • 类错误不存在默认构造函数

    一些简单的代码 class Thing public int num Thing int num this gt num num class Stuff public Thing thing an instance of thing is
  • 使用 Java 从文本中删除重复行

    我想知道是否有人在java中具有删除重复行同时保持行顺序的逻辑 我不喜欢正则表达式解决方案 public class UniqueLineReader extends BufferedReader Set
  • 如何在网格视图中显示文件夹中的图像?

    如何显示gridview中路径存储在ms sql数据库中的文件夹中的图像 这是一个非常常见的任务 微软有代码示例 看这里 http msdn microsoft com en us library aa479350 aspx
  • 定位非数字索引值的数字位置

    考虑系列s below s pd Series np arange 18 0 3 list ABCDEF s A 18 B 15 C 12 D 9 E 6 F 3 dtype int32 我想得到的数字位置 D 这样就可以了 但我想我们都同
  • (C语言)如何在使用getchar()时使用退格键;在这个函数中?

    你好 抱歉 如果我听不懂 我是 C 编程新手 而且我不是最好的英语作家 我的问题 我无法理解如何在使用代码时使用退格键 我很高兴有人能向我解释它是如何工作的 include
  • 如何让 Laravel Vite 将版本化的静态资源复制到构建文件夹

    我正在尝试 Laravel Vite 但似乎无法弄清楚如何让构建命令移动静态资源 相反 它通过 Base64 将图像 嵌入 CSS 文件中 到目前为止 我发现您需要引用相对于源 css scss 文件的图像 就像这样在 resources
  • 修改 jQuery ajax 请求连接标头

    我尝试使用以下代码修改连接标头 但没有成功 jQuery ajax url URL async boolVariable beforeSend function xhr xhr setRequestHeader Connection clo
  • Geode本机客户端反序列化Pdx实例Impl

    我有一个 REST 客户端 它使用 Json 数据填充 Geode 区域 Geode REST API 会自动将其转换为 PdxInstance 类型 该区域触发 C 本机客户端侦听器AfterCreate EntryEvent
  • 向 Rails 中的所有用户发送电子邮件

    我正在尝试创建一种方法 在调用时向所有用户发送电子邮件 我的最终目标是通过调度程序调用此方法 我已经让调度程序正常工作 并且该方法将考虑所有用户并向其中一些用户发送电子邮件 如果满足某些先决条件 现在我只想了解如何制作最简单的东西 即向表中
  • 如何将 dropbox csv 文件下载到 pandas

    我对网络抓取不熟悉 我找到了一些说明 但我不确定从这里还能做什么 单击链接会自动下载 csv 文件 如何通过网络抓取将其获取到我的 pandas jupyter 笔记本 import urllib request url https www
  • 由于在多个 cpp 中包含相同标头而导致重复的多个定义错误

    因此 无论我做什么 我似乎都无法避免 Dev C 抛出大量多重定义错误 因为我在同一项目的多个源代码文件中包含相同的头文件 我强烈希望避免将所有源代码转储到一个文件中 并且只包含一次标头 因为这将使我的文件非常长且难以管理 本质上 这是发生