如何查找函数的多个定义

2024-02-26

我写了一个 findDialog 来查找搜索的文本。当我给予make命令,它返回

g++ -Wl,-O1 -o findDialog FindDialog.o main.o moc_FindDialog.o    -L/usr/lib -lQtGui -lQtCore -lpthread 
moc_FindDialog.o: In function `FindDialog::findClicked()':
moc_FindDialog.cpp:(.text+0x20): multiple definition of `FindDialog::findClicked()'
FindDialog.o:FindDialog.cpp:(.text+0x30): first defined here
moc_FindDialog.o: In function `FindDialog::enableFindButton(QString const&)':
moc_FindDialog.cpp:(.text+0x50): multiple definition of `FindDialog::enableFindButton(QString const&)'
FindDialog.o:FindDialog.cpp:(.text+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [findDialog] Error 1

我已经搜索了这个问题几个小时,但我不明白问题出在哪里。 什么会导致multiple definition of error?


当方法定义包含在多个翻译单元(也称为目标文件)中时,通常会发生这种情况。后来,当链接器组合这些目标文件时,它发现同一方法有多个定义,并抱怨因为它不知道使用哪一个。下面是一个如何引入此错误的简单示例:

有头文件header.hpp包含方法声明及其定义:

class foo {
public:
  void bar ();
};

void foo::bar ()
{
}

并有两个源文件 source1.cpp 和 source2.cpp 都包含该文件:

source1.cpp:

#include "header1.hpp"
int example1()
{
  foo f;
  f.bar ();
}

... and source2.cpp:

#include "header1.hpp"
int main ()
{
  foo f;
  f.bar ();
  f.bar ();
}

然后,分别编译两个文件并将它们链接在一起。例如:

g++ -c source1.cpp source1.o
g++ -c source2.cpp source2.o
g++ -o a.out source1.o source2.o

这会给你一个你在问题中描述的链接器错误,因为方法foo::bar在 source1 和 source2 对象中出现两次。链接器不知道该使用哪一个。

此问题有两种常见的解决方案:

解决方案#1 - 内联该方法。

通过声明该方法inline关键字,编译器将内联整个方法,或者,如果决定不内联,它将生成匿名方法(相同的方法,但对于给定的目标文件具有一些唯一的名称),因此目标文件中不会发生冲突。例如:

class foo {
public:
  void bar ();
};

inline void foo::bar ()
{
}

解决方案#2 - 在另一个源文件中定义(实现)该方法,以便它在整个程序中仅出现一次。例如:

header1.hpp:

class foo {
public:
  void bar ();
};

header1.cpp:

#include "header1.hpp"
void foo::bar ()
{
}

要决定是否内联,您必须知道(或至少猜测)调用此函数是否比在整个程序中重复/内联此代码更昂贵。内联代码通常会使您的程序变得更大并增加编译时间。但这并不一定会使速度更快。另外,在源文件中有定义不会导致使用该函数重新编译所有源文件,而只会重新编译有定义的源文件,然后重新链接。许多程序员对 C++ 内联感到疯狂,但没有真正理解它如何影响程序。我建议仅在调用该函数成为性能瓶颈时才使用源文件中的定义并将其内联,否则将其内联将修复它。

希望能帮助到你。快乐编码!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何查找函数的多个定义 的相关文章

随机推荐