如何找到一个函数的多个定义 [英] How to find the multiple definitions of a function

查看:144
本文介绍了如何找到一个函数的多个定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I wrote a findDialog which finds the text searched. When I give make command,it returns

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

我已经搜索了几个小时的问题,但我不明白问题来自何处。
可能导致 多重定义的错误?

I have searched the problem for hours, but I can not understand what the problem stems from. What can cause multiple definition of error?

推荐答案

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

It usually happens when method definition is included in multiple translation units, also called as object files. Later, when linker is combining those object files, it finds out that there are multiple definitions of the same method, and complains because it doesn't know which one to use. Here is a simple example of how to introduce this error:

有头文件 header.hpp 及其定义:

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

void foo::bar ()
{
}


$ b b

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

And have two source files source1.cpp and source2.cpp both including that file:

source1.cpp

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

...和 source2.cpp

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

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

Then, compile two files separately and link them together. For example:

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

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

That will give you a linker error you have described in your question, because method foo::bar appears twice, in both source1 and source2 objects. Linker doesn't know which one to use.

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

There are two common solutions to this problem:

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

Solution #1 - Have that method inlined.

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

By declared that method with inline keyword, compiler will either inline the whole method or, if it decides not to, it will generate anonymous method (same method but with some unique name for a given object file), so there will be no conflicts in object files. For example:

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

inline void foo::bar ()
{
}

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

Solution #2 - Have definition (implementation) of that method in another source file, so that it appears only once in the whole program. For example:

header1.hpp

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

header1.cpp

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

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

To decide whether to inline or not, you have to know (or at least make a guess) whether calling this function is more expensive than having this code duplicated / inlined all over the program. Inlined code usually makes your program bigger and increases compilation time. But it doesn't necessarily make it faster. Plus, having definition in source file will not result in re-compilation of all source files using that function, but only re-compilation of the source file that has definition, and then re-linking. Many programmers are going crazy about C++ inlining without really understanding how it affects the program. I'd recommend going with the definition in a source file and making it inline only if calling that function becomes a performance bottleneck and otherwise having it inlined will fix it.

Hope它有助于。快乐编码!

Hope it helps. Happy coding!

这篇关于如何找到一个函数的多个定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆