多重定义... | C++

Multiple Definitions of... | C++

这是一个有点理论性的问题...

我一直在阅读 linking object 文件。现在我收到有关某些函数的多个定义的错误消息。我相信已确定问题如下:

我假设问题是,在 AO 和 BO 中都以某种方式引用或编译代码到/从 H,所以当我 link AO ad BO 编译 M 时它出现两次。我有没有认识到问题正确,还是我可能遗漏了什么?

如果是这样,您如何避免或解决此类问题?

编辑:我说我编译了 header 个文件。抱歉,这样说很草率。我用 header 文件 A 和 B 中 class 方法的实现编译了 cpp 文件。

你还记得 header 文件中的 header 守卫吗,否则你会遇到这个问题。

#ifndef MY_HEADER_H_INC
#define MY_HEADER_H_INC

/* Put Header Code Here */

#endif // MY_HEADER_H_INC

您最终会多次包含同一个文件,因为正如您所说的那样,您在两个文件中都包含 header H,然后再包含每个文件。这听起来是最有可能的原因。

永远不要编译 .h(头文件)文件。 头文件 是一个 C++ 源文件,旨在通过 #include 指令包含在其他 C++ 源文件中。

您应该编译的唯一文件是 .cpp 文件,这些文件通常称为 实施文件

不要在头文件中包含函数定义也很重要。每个函数定义只能编译一次,因此必须编码到一个实现文件中。头文件应仅包含:

  • 转发声明
  • 其他#includes
  • 类型
  • 外部人员
  • 模板代码
  • 函数原型

您的问题的原因很可能是您在 H 文件中包含了完整的函数定义,因此,当您编译 A 和 B 实现文件(它们应该被称为 实现文件 如果你正在编译它们;或者,你可以考虑将函数定义从那些头文件移动到单独的实现文件中,并且只编译 那些 实现文件),函数是被编译成 AO 和 BO 目标文件。这就是 linking 失败的原因;函数在 link 时间被多重定义。

要解决此问题,您需要将 H 头文件中的所有函数定义移动到单独的实现文件中。由于 H 似乎没有绑定到您已经拥有的任何单个实现文件(我这样说是因为它似乎是 A 和 B 的依赖项),将这些函数定义移动到一个新的 H.cpp 实现文件。作为构建过程的一部分,您必须在 link 时将 H.cpp 和 link 构建到最终的可执行文件中。

在 C++ 中,您应该将声明与实现分开以避免重新定义(如您所描述的情况)。将声明放入 header 文件 filename.h,其中包含某种 include guard(#def-based 或 #pragma once);将您的定义放入 filename.cpp,其中包括通过 #include "filename.h" 的 header。编译时,只编译 .cpp 文件;不要尝试编译 headers(除非你需要一个预编译的 header,而你可能不需要)。