首先让我说我不是最好的C ++,而且我对Linux的方式知之甚少。对于一个类项目,我们必须实现一个堆,所以我在Windows PC上对所有内容进行了编码,假设我可以将文件上传到学校的Linux存储库中。 [也许这就是我出错的地方,这不能简单地完成。]我的代码编译并清除我的Windows PC上提供的所有测试用例。当我将文件上传到Linux时,我创建了一个makefile,当我使用make命令时,我找回了多个定义错误的清单。我正在使用的每个功能一个错误。我做了一些搜索,当我开始时我更加困惑。
我的文件是:main.cpp,main.h,heap.cpp,heap.h,util.cpp和util.h。
我认为问题出在我的包含声明中,但我不是百分百肯定。
以下是文件的示例。
的main.cpp
#include <iostream> //needed to use basic inputs/outputs
#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#include "util.cpp"
#include "heap.cpp"
#include <fstream>
using namespace std;
main.h是空白的。
heap.cpp
#include <iostream> //needed to use basic inputs/outputs
#include <stdio.h>
#include <stdlib.h>
#include "heap.h"
#include <cmath>
#include <math.h>
using namespace std;
//expanded functions found in the heap.h file
heap.h
//2 structs
//9 functions
util.cpp
#include <iostream> //needed to use basic inputs/outputs
#include <stdio.h>
#include <stdlib.h>
#include "util.h"
using namespace std;
//expanded functions found in util.h
util.h
//1 function
在heap.h和util.h之间我有10个函数,在运行make命令后,我得到一个关于所有十个的警告:
multiple definition of 'FUNCTIONNAME'
main.o:main.cpp:(.text+0x1b7): first defined here
我假设0x1b7是一个内存位置,因为它们各不相同。
非常感谢任何帮助。
答案 0 :(得分:2)
您还没有显示Makefile,但很有可能,它包含此规则或类似规则
program: main.o heap.o util.o
$(CXX) $(CXXFLAGS) -o program main.o heap.o util.o
现在发生了什么,编译器构建了三个目标文件main.o,heap.o和util.o.接下来,将目标文件链接在一起以构建program
。
链接器分别看到main.o和heap.o或main.o和util.o中定义的各种函数的定义。这就是为什么它抱怨&#34; FUNCTIONNAME&#39;&#34;
的多重定义为什么这些功能定义不止一次?
将文件包含到其他来源时,就像复制#include
位置的内容一样。这意味着在heap.cpp中定义的函数:
void create_heap(int size)
{
// create a heap ...
}
逐字复制到main.cpp中的行
#include "heap.cpp"
是
因为heap.cpp具有create_heap()
和main.cpp #include
的定义,所以heap.cpp的内容都包含它们自己的create_heap()
副本。现在编译heap.o和main.o,并将它们链接在一起。每个目标文件都有create_heap()
的副本,这是链接器混淆和抱怨的地方
multiple definition of 'create_heap'
main.o:main.cpp:(.text+0x1b7): first defined here
要解决此问题,只需替换包含cpp源的行,例如
#include "util.cpp"
#include "heap.cpp"
及其各自的头文件
#include "util.h"
#include "heap.h"
只保留与main.cpp相关的函数定义,没有别的。现在main.cpp没有属于util.cpp或heap.cpp的函数定义,并且链接器错误消失了。
据推测,这适用于Windows,因为只有main.cpp包含在项目文件中,因此在生成的可执行文件中只有一个定义(来自main.o)。
如果你在Linux Makefile中包含了所有来源,那么在Windows中也可以看到错误。