此功能是全局的,在头文件中定义(暂时我想保留它)。
头文件也构成一个具有内联函数的特定类,其中一个函数调用 this 全局函数。
源文件不包含任何有问题的全局函数。
有关错误原因的任何提示?
如果有人有兴趣,我可以发布代码。
mainwindow.o: In function `tileForCoordinate(double, double, int)':
mainwindow.cpp:(.text+0x310): multiple definition of `tileForCoordinate(double, double, int)'
main.o:main.cpp:(.text+0xd0): first defined here
moc_mainwindow.o: In function `qHash(QPoint const&)':
moc_mainwindow.cpp:(.text+0x0): multiple definition of `qHash(QPoint const&)'
main.o:main.cpp:(.text+0x0): first defined here
moc_mainwindow.o: In function `tileForCoordinate(double, double, int)':
moc_mainwindow.cpp:(.text+0x150): multiple definition of `tileForCoordinate(double, double, int)'
main.o:main.cpp:(.text+0xd0): first defined here
collect2: ld returned 1 exit status
make: *** [SimpleRouting] Error 1
答案 0 :(得分:28)
将其标记为inline
:
inline void globalfunc() {
}
尽管这样做意味着它将不再严格地是全局的 - 您将在每个使用标头的翻译单元中获得副本,但链接器不会反对此。
答案 1 :(得分:10)
如果您在标题中放置了一个函数,它将为每个包含该标题的c / cpp文件生成,从而导致重复。使其内联将有所帮助。
修改,解释
标题保护作为#ifndef,#define ... #endif构造通常只调用单个cpp文件中的双重和递归包含。这与源文件包含标题A和B以及B还包括A的情况相关。如果A也包含B,则会发生递归包含。
您的问题出现是因为您有多个.cpp文件。在编译一个cpp期间,编译器不知道其他cpp文件的存在。
请注意,#include,#iff和friends是预处理程序指令。在编译之前对源文件进行预处理(认为它通常被视为编译过程的一部分)。预处理器基本上是文本处理器。例如,#include在文本上被替换为头文件的内容。评估为false的#ifdefs的内容将从代码中删除。实际编译器获取一个由cpp和所有引用的包含文件组成的大文件,它将它转换为目标文件。
答案 2 :(得分:9)
您有两个选择:
将其标记为内联,如nbt所述,或静态。
inline将从源代码中执行全局函数,并将其复制到函数调用的任何位置。
inline void global_func ()
{
...
}
static会告诉链接器不要将代码复制到新的目标文件中,而只是在原始文件中引用它。
static void global_func ()
{
...
}
答案 3 :(得分:4)
对于头文件中定义的全局函数,在未命名的命名空间中声明它应该/也可以。根据Dexel的C ++ How to Program,在C ++中,一个未命名的命名空间优于静态。
所以你可以这样做:
// \file GlobalFunctions.h
namespace // an un-named namespace
{
void GlobalFunctionOne() {...implementation...}
} // end un named namespace
答案 4 :(得分:-2)
#ifndef SOMESTRING
#define SOMESTRING
... header code
#endif
标题的代码将仅在第一次包含。