C ++:头文件中全局函数的多个定义错误

时间:2011-05-21 09:28:32

标签: c++ qt multiple-definition-error

此功能是全局的,在头文件中定义(暂时我想保留它)。

头文件也构成一个具有内联函数的特定类,其中一个函数调用 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

5 个答案:

答案 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

标题的代码将仅在第一次包含。