C++包括“.h”文件、函数重复混乱

发布于 2024-11-07 12:36:10 字数 1093 浏览 0 评论 0原文

我目前正在编写一个程序,无法弄清楚为什么会出现错误(注意:我已经修复了它,我很好奇为什么会出现错误以及这对于包含 .h 文件意味着什么)。

基本上,我的程序结构如下:

我正在使用的当前文件,我将调用 Current.cc (它是 Current.h 的实现)。

Current.cc 包含一个名为 CalledByCurrent.h 的头文件(它有一个名为 CalledByCurrent.cc 的关联实现)。 CalledByCurrent.h 包含一个类定义。

CalledByCurrent.cc 中定义了一个名为 thisFunction() 的非类函数。 thisFunction() 未在 CalledByCurrent.h 中声明,因为它实际上不是类的成员函数(只是一个小辅助函数)。在Current.cc中,我需要使用这个函数,所以我只是在Current.cc顶部重新定义了thisFunction()。然而,当我这样做时,我收到一个错误,指出该函数已重复。当 myFunction() 甚至没有在 CalledByCurrent.h 中声明时,为什么会出现这种情况?

因此,我刚刚从 Current.cc 中删除了该函数,现在假设 Current.cc 可以从 CalledByCurrent 访问 thisFunction() .cc。然而,当我这样做时,我发现Current.cc不知道我在说什么函数。到底是什么?然后,我将 thisFunction() 的函数定义复制到 CalledByCurrent.h 文件的顶部,这解决了问题。你能帮我理解这种行为吗?特别是,为什么它会认为有重复的,却不知道如何使用原始的?

ps - 对于这篇文章的混乱之处,我深表歉意。如果有什么我可以解决的问题,请告诉我。

I'm currently writing a program, and couldn't figure out why I got an error (note: I already fixed it, I'm curious about WHY the error was there and what this implies about including .h files).

Basically, my program was structured as follows:

The current file I'm working with, I'll call Current.cc (which is an implementation of Current.h).

Current.cc included a header file, named CalledByCurrent.h (which has an associated implementation called CalledByCurrent.cc). CalledByCurrent.h contains a class definition.

There was a non-class function defined in CalledByCurrent.cc called thisFunction(). thisFunction() was not declared in CalledByCurrent.h since it was not actually a member function of the class (just a little helper function). In Current.cc, I needed to use this function, so I just redefined thisFunction() at the top of Current.cc. However, when I did this, I got an error saying that the function was duplicated. Why is this, when myFunction() wasn't even declared in CalledByCurrent.h?

Thus, I just removed the function from Current.cc, now assuming that Current.cc had access to thisFunction() from CalledByCurrent.cc. However, when I did this, I found that Current.cc did not know what function I was talking about. What the heck? I then copied the function definition for thisFunction() to the top of my CalledByCurrent.h file and this resolved the problem. Could you help me understand this behavior? Particularly, why would it think there was a duplicate, yet it didn't know how to use the original?

p.s - I apologize for how confusing this post is. Please let me know if there's anything I can clear up.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

赴月观长安 2024-11-14 12:36:10

您从链接器获得多个定义 - 它看到两个具有相同名称的函数并抱怨。例如:

// a.cpp
void f() {}

// b.cpp
void f() {}

then

g++ a.cpp b.cpp

给出:

C:\Users\neilb\Temp\ccZU9pkv.o:b.cpp:(.text+0x0): multiple definition of `f()'

解决这个问题的方法是将定义仅放在一个 .cpp 文件中,或者将一个或两个函数声明为静态:

// b.cpp
static void f() {}

You are getting multiple definitions from the linker - it sees two functions with the same name and complains. For example:

// a.cpp
void f() {}

// b.cpp
void f() {}

then

g++ a.cpp b.cpp

gives:

C:\Users\neilb\Temp\ccZU9pkv.o:b.cpp:(.text+0x0): multiple definition of `f()'

The way round this is to either put the definition in only one .cpp file, or to declare one or both of the functions as static:

// b.cpp
static void f() {}
烟酉 2024-11-14 12:36:10

不能有两个同名的全局函数(即使在两个不同的翻译单元中)。为了避免出现链接器错误,请将函数定义为static,以便它在翻译单元之外不可见。

编辑

您可以通过使用extern关键字来使用其他.cpp文件中的函数。请参阅此示例:

//Test.cpp

void myfunc()
{

}

//Main.cpp
extern void myfunc();
int main()
{
    myfunc();
}

它将调用 test.cpp 中定义的 myfunc()

You can't have two global functions with the same name (even in 2 different translation units). To avoid getting the linker error define the function as static so that it is not visible outside the translation unit.

EDIT

You can use the function in the other .cpp file by using extern keyword. See this example:

//Test.cpp

void myfunc()
{

}

//Main.cpp
extern void myfunc();
int main()
{
    myfunc();
}

It will call myfunc() defined in test.cpp.

用心笑 2024-11-14 12:36:10

头文件包含机制应该能够容忍重复的头文件包含。

The header file inclusion mechanism should be tolerant to duplicate header file inclusions.

忆梦 2024-11-14 12:36:10

这是因为每当您简单地声明一个函数时,它都会被视为在 extern(全局)范围内(无论您是否在头文件中声明它)。链接器对于同一函数签名将有多个实现。

如果这些函数确实是辅助函数,则将它们声明为;

static void thisFunction();

换句话说,如果您使用与 helper 相同的函数,只需在公共头文件中声明它,例如:

//CalledByCurrent.h  (is included in both .cc files)
void thisFunction();

在任一 .cc 文件中实现 thisFunction()。这应该可以正确解决问题。

That's because whenever you simply declare a function it's considered in extern (global) scope (whether you declare it in a header file or not). Linker will have multiple implementation for the same function signature.

If those functions are truely helper functions then, declare them as;

static void thisFunction();

Other way, if you are using the same function as helper then, simply declare it in a common header file, say:

//CalledByCurrent.h  (is included in both .cc files)
void thisFunction();

And implement thisFunction() in either of the .cc files. This should solve the problem properly.

野侃 2024-11-14 12:36:10

以下是一些想法:

  • 您没有放置 标头包含防护 在你的头文件中。如果它被包含两次,您可能会收到此类错误。
  • 该函数的原型(位于顶部)与其签名不 100% 匹配。
  • 您将函数的主体放在头文件中。
  • 您在两个不同的源文件中有两个具有相同签名的函数,但它们未标记为static

如果您使用的是 gcc(您没有说明您正在使用什么编译器),则可以使用 -E 开关查看预处理器输出。这包括扩展所有#define并包含所有#include

每次展开某些内容时,它都会告诉您它所在的文件和行。使用它您可以看到 thisFunction() 的定义位置。

Here are some ideas:

  • You didn't put a header include guard in your header file. If it's being included twice, you might get this sort of error.
  • The function's prototype (at the top) doesn't match its signature 100%.
  • You put the body of the function in the header file.
  • You have two functions of the same signature in two different source files, but they aren't marked static.

If you are using gcc (you didn't say what compiler you're using), you can use the -E switch to view the preprocessor output. This includes expanding all #defines and including all #includes.

Each time something is expanded, it tells you what file and line it was in. Using this you can see where thisFunction() is defined.

辞慾 2024-11-14 12:36:10

有 2 个不同的错误来自构建的两个不同阶段。

在第一种情况下,如果有一个重复项,编译器会很高兴,但链接器会抱怨,因为当它拾取不同源文件中的所有函数定义时,它会注意到两个名称相同。正如其他答案所述,您可以使用 static 关键字或使用通用定义。

在第二种情况下,您看到您的函数未在此范围内声明,这是因为编译器正在抱怨,因为每个文件都需要知道它可以使用哪些函数。

编译发生在链接之前,因此编译器无法提前知道链接器是否会找到匹配的函数,这就是为什么您使用声明来通知编译器稍后链接器将找到定义。

正如您所看到的,您的两个错误并不矛盾,它们是构建中具有特定顺序的两个单独进程的结果。

There are 2 distinct errors coming from 2 different phases of the build.

In the first case where you have a duplicate, the COMPILER is happy, but the LINKER is complaining because when it picks up all the function definitions across the different source files it notices 2 are named the same. As the other answers state, you can use the static keyword or use a common definition.

In the second case where you see your function not declared in this scope, its because the COMPILER is complaining because each file needs to know about what functions it can use.

Compiling happens before Linking, so the COMPILER cannot know ahead of time whether or not the LINKER will find a matching function, thats why you use declarations to notify the COMPILER that a definition will be found by the LINKER later on.

As you can see, your 2 errors are not contradictory, they are the result of 2 separate processes in the build that have a particular order.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文