C++包括“.h”文件、函数重复混乱
我目前正在编写一个程序,无法弄清楚为什么会出现错误(注意:我已经修复了它,我很好奇为什么会出现错误以及这对于包含 .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()
.ccCurrent.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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您从链接器获得多个定义 - 它看到两个具有相同名称的函数并抱怨。例如:
then
给出:
解决这个问题的方法是将定义仅放在一个 .cpp 文件中,或者将一个或两个函数声明为静态:
You are getting multiple definitions from the linker - it sees two functions with the same name and complains. For example:
then
gives:
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:
不能有两个同名的全局函数(即使在两个不同的翻译单元中)。为了避免出现链接器错误,请将函数定义为
static
,以便它在翻译单元之外不可见。编辑
您可以通过使用
extern
关键字来使用其他.cpp
文件中的函数。请参阅此示例:它将调用
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 usingextern
keyword. See this example:It will call
myfunc()
defined intest.cpp
.头文件包含机制应该能够容忍重复的头文件包含。
The header file inclusion mechanism should be tolerant to duplicate header file inclusions.
这是因为每当您简单地声明一个函数时,它都会被视为在 extern(全局)范围内(无论您是否在头文件中声明它)。链接器对于同一函数签名将有多个实现。
如果这些函数确实是辅助函数,则将它们声明为;
换句话说,如果您使用与 helper 相同的函数,只需在公共头文件中声明它,例如:
并在任一 .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;
Other way, if you are using the same function as helper then, simply declare it in a common header file, say:
And implement thisFunction() in either of the .cc files. This should solve the problem properly.
以下是一些想法:
static
。如果您使用的是 gcc(您没有说明您正在使用什么编译器),则可以使用
-E
开关查看预处理器输出。这包括扩展所有#define
并包含所有#include
。每次展开某些内容时,它都会告诉您它所在的文件和行。使用它您可以看到
thisFunction()
的定义位置。Here are some ideas:
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#define
s and including all#include
s.Each time something is expanded, it tells you what file and line it was in. Using this you can see where
thisFunction()
is defined.有 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.