这是一个有点理论上的问题......
我一直在阅读链接目标文件。现在我收到有关某些函数的多个定义的错误消息。我相信已将问题确定如下:
我有两个单独的头文件A和B.
两个标题都访问相同的标题H.
从A和B我编译了目标文件AO和BO。
当我尝试通过将AO和BO链接到M来编译包含A和B的cpp-File M时,我收到有关多个定义的错误消息。
错误信息所涉及的功能位于H.
我认为问题是,AO和BO在某种程度上都是H的引用或编译代码,因此当我在编译M时链接AO ad BO时它会出现两次。我是否正确识别了问题,或者我是我可能错过了一些东西?
如果是这样,你如何避免或解决这个问题?
编辑:我说我编译了头文件。对不起,这是说话的草率方式。我使用头文件A和B中的类方法的实现编译了cpp文件。
答案 0 :(得分:1)
您永远不应该编译.h
(标题)文件。 头文件是一个C ++源文件,它通过#include
指令包含在其他C ++源文件中。
您应编译的唯一文件是.cpp
个文件,通常称为实施文件。
在头文件中不包含函数定义也很重要。每个函数定义只能编译一次,因此必须编码为一个实现文件。头文件应仅包含:
#include
s 您的问题的原因很可能是您在H文件中包含了一个完整的函数定义,因此,当您编译A和B实现文件时(它们应该被称为实现文件,如果您正在编译它们;或者,您可以考虑将这些头文件中的函数定义移动到单独的实现文件中,并且只编译那些实现文件),该函数被编译为AO和BO对象文件。这就是链接失败的原因;函数在链接时被多次定义。
要解决此问题,您需要将H头文件中的任何函数定义移动到单独的实现文件中。由于H似乎与您已经拥有的任何单个实现文件无关(我说这是因为它似乎是A和B的依赖),因此将这些函数定义移动到新的H中可能是最有意义的。 cpp实现文件。作为构建过程的一部分,您将必须构建H.cpp,并在链接时将其链接到最终的可执行文件。
答案 1 :(得分:0)
您是否记得头文件中的标题保护,否则您最终会遇到此问题。
#ifndef MY_HEADER_H_INC
#define MY_HEADER_H_INC
/* Put Header Code Here */
#endif // MY_HEADER_H_INC
您最终会多次包含同一个文件,因为正如您所说的那样,两者都包含标题H,那么您可以包括每个文件。这听起来像是最可能的原因。
答案 2 :(得分:0)
在C ++中,您应该将声明与实现分开,以避免重新定义(如您所描述的情况)。将声明放入头文件filename.h中,其中包含一些include guard(基于#define或#pragma一次);将您的定义放在filename.cpp中,其中包括#include" filename.h"的标题。编译时,只编译.cpp文件;不要尝试编译头文件(除非你需要一个预编译的头文件,你可能不需要)。