多重定义... | C++
Multiple Definitions of... | C++
这是一个有点理论性的问题...
我一直在阅读 linking object 文件。现在我收到有关某些函数的多个定义的错误消息。我相信已确定问题如下:
我有两个单独的 header 文件 A 和 B。
两个 header 访问相同的 header H。
我从 A 和 B 编译了 object 个文件 AO 和 BO。
当我尝试通过link将AO 和BO 编译为M 来编译包含A 和B 的cpp-File M 时,我收到有关多个定义的错误消息。
错误消息所涉及的函数位于 H 中。
我假设问题是,在 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
文件,这些文件通常称为 实施文件 。
不要在头文件中包含函数定义也很重要。每个函数定义只能编译一次,因此必须编码到一个实现文件中。头文件应仅包含:
- 转发声明
- 宏
- 其他
#include
s
- 类型
- 外部人员
- 模板代码
- 函数原型
您的问题的原因很可能是您在 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,而你可能不需要)。
这是一个有点理论性的问题...
我一直在阅读 linking object 文件。现在我收到有关某些函数的多个定义的错误消息。我相信已确定问题如下:
我有两个单独的 header 文件 A 和 B。
两个 header 访问相同的 header H。
我从 A 和 B 编译了 object 个文件 AO 和 BO。
当我尝试通过link将AO 和BO 编译为M 来编译包含A 和B 的cpp-File M 时,我收到有关多个定义的错误消息。
错误消息所涉及的函数位于 H 中。
我假设问题是,在 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
文件,这些文件通常称为 实施文件 。
不要在头文件中包含函数定义也很重要。每个函数定义只能编译一次,因此必须编码到一个实现文件中。头文件应仅包含:
- 转发声明
- 宏
- 其他
#include
s - 类型
- 外部人员
- 模板代码
- 函数原型
您的问题的原因很可能是您在 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,而你可能不需要)。