C++包括".h"文件,功能重复混淆
C++ including a ".h" file, function duplication confusion
我目前正在编写一个程序,无法弄清楚为什么会出现错误(注意:我已经修复了它,我很好奇为什么会出现错误以及这意味着什么包括.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.cc
访问thisFunction()
。 但是,当我这样做时,我发现Current.cc
不知道我在说什么功能。 什么鬼? 然后,我将thisFunction()
的函数定义复制到CalledByCurrent.h
文件的顶部,这解决了问题。 你能帮我理解这种行为吗? 特别是,为什么它会认为有副本,但它不知道如何使用原件?
p.s - 对于这篇文章的混乱程度,我深表歉意。 如果有什么我可以澄清的,请告诉我。
您正在从链接器获得多个定义 - 它看到两个同名的函数并抱怨。例如:
// a.cpp
void f() {}
// b.cpp
void f() {}
然后
g++ a.cpp b.cpp
给:
C:UsersneilbTempccZU9pkv.o:b.cpp:(.text+0x0): multiple definition of `f()'
解决方法是将定义仅放在一个.cpp文件中,或者将一个或两个函数声明为静态:
// b.cpp
static void f() {}
不能有两个同名的全局函数(即使在 2 个不同的翻译单元中也是如此)。为避免出现链接器错误,请将函数定义为static
,使其在翻译单元外不可见。
编辑
您可以使用extern
关键字在其他.cpp
文件中使用该函数。请参阅此示例:
//Test.cpp
void myfunc()
{
}
//Main.cpp
extern void myfunc();
int main()
{
myfunc();
}
它将调用test.cpp
中定义的myfunc()
。
头文件包含机制应容忍重复的头文件包含。
这是因为每当你简单地声明一个函数时,它都会被考虑在extern
(全局)范围内(无论你是否在头文件中声明它)。链接器将具有同一函数签名的多个实现。
如果这些函数确实是帮助程序函数,则将它们声明为;
static void thisFunction();
另一种方式,如果您使用与 helper 相同的函数,那么只需在公共头文件中声明它,例如:
//CalledByCurrent.h (is included in both .cc files)
void thisFunction();
并在任一 .cc 文件中实现 thisFunction()。这应该可以正确解决问题。
这里有一些想法:
- 您没有在头文件中放置标头包含保护。 如果它被包含两次,您可能会收到此类错误。
- 函数的原型(顶部)与其签名 100% 不匹配。
- 将函数的主体放在头文件中。
- 您在两个不同的源文件中有两个具有相同签名的函数,但它们未标记为
static
。
如果您使用的是 gcc(您没有说明您正在使用的编译器),则可以使用 -E
开关查看预处理器输出。 这包括扩展所有#define
并包括所有#include
。
每次展开某些内容时,它都会告诉您它在哪个文件和行中。 使用它,您可以看到定义thisFunction()
的位置。
2 个不同的错误来自构建的 2 个不同阶段。
在第一种情况下,您有一个重复项,编译器很高兴,但 LINKER 抱怨,因为当它拾取不同源文件中的所有函数定义时,它注意到 2 个被命名为相同。如其他答案所述,您可以使用 static 关键字或使用通用定义。
在第二种情况下,您看到您的函数未在此范围内声明,这是因为 COMPILER 抱怨,因为每个文件都需要知道它可以使用哪些函数。
编译发生在链接之前,因此编译器无法提前知道链接器是否会找到匹配的函数,这就是为什么您使用声明来通知编译器稍后链接器将找到定义。
如您所见,您的 2 个错误并不矛盾,它们是构建中具有特定顺序的 2 个独立进程的结果。
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 多态性和功能结合
- 带内存和隔离功能的SQLite
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 如何在C++中获得"静态纯虚拟"功能?
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- C //尝试重写一个工作代码以包括我的功能
- C++继承 - 覆盖功能,包括使用 "::" s、.h 文件和.cpp文件
- 确实被认为是实验性的 - 静态反射功能包括对母类的迭代
- c4710 功能不包括在内 std::basic_ostream
- 功能指针数组(包括成员功能)投掷模板专业化错误
- #包括在功能体内部或降低其可见性
- 提升单元测试框架:包括我的代码库的主要功能
- C或C++或WinApi中是否有任何功能来创建目录,包括指定路径中所有不存在的目录
- 包括一个库是否会破坏C++中另一个库的功能
- 包括ping超时功能
- C++包括".h"文件,功能重复混淆