C++ 为什么包含.h也会使.cpp源与它一起出现?
我是一个有经验的程序员,但只会高级语言;我现在正在做我的第一个真正的C++大型工程。 我有两门课,C++ 为什么包含.h也会使.cpp源与它一起出现?,c++,compilation,linker,C++,Compilation,Linker,我是一个有经验的程序员,但只会高级语言;我现在正在做我的第一个真正的C++大型工程。 我有两门课,ClassA和ClassB;ClassA是ClassB的索引,因此ClassA需要知道什么是ClassB来构建数组,而ClassB需要知道什么是ClassA以便在发生变化时可以更新索引。这两个类都位于各自的.h和.cpp文件中 我认为从另一个包含每一个只会导致无限递归,所以我决定在main.cpp的开头包含#include“ClassA.cpp”和#include“ClassB.cpp”;但这样做只
ClassA
和ClassB
;ClassA
是ClassB
的索引,因此ClassA
需要知道什么是ClassB
来构建数组,而ClassB
需要知道什么是ClassA
以便在发生变化时可以更新索引。这两个类都位于各自的.h和.cpp文件中
我认为从另一个包含每一个只会导致无限递归,所以我决定在main.cpp
的开头包含#include“ClassA.cpp”和#include“ClassB.cpp”
;但这样做只会导致编译器警告这些文件中每个类和方法的多个定义
经过一些实验,我发现包含ClassA.h
和ClassB.h
会产生所需的行为-但这没有任何意义,我只包含了这些类的原型。当然,真正构成它们的代码永远不会被混入其中?但事实确实如此
这里发生了什么我不明白的事?为什么包含ClassA.h
也会使ClassA
的实际代码随之显示?为什么包含ClassA.cpp
会导致ClassA.h
的每个包含触发“多重定义”错误,即使它们在标题屏蔽中或任何它被称为的地方?缺少的步骤是链接器将看不到ClassA.cpp
和ClassB.cpp
中的定义,除非这些文件在某个时候也被编译。如果您这样做:
g++ main.cpp ClassA.cpp ClassB.cpp
然后,将解析main.cpp
中对ClassA.cpp
和ClassB.cpp
中定义的所有引用。然而,如果你这么做的话
g++ main.cpp
然后链接器将不知道在哪里可以找到ClassA.cpp
和ClassB.cpp
中的定义,您可能会得到一个错误
如果使用井手,则该细节将被隐藏:IDE确保只要在项目中添加.CPP文件,在构建项目时,它将被编译成最终二进制。
< P>这是C++设计的方式:
您的类现在不需要比其他类的原型更多的东西,因此您只需要包含标题
为什么会这样?一个完整的应用程序的编译是两个步骤的组合:代码本身的编译然后链接(实际上,前面有第三个步骤:预处理,但是我们可以把这个作为代码编译的一部分)。
函数调用示例:知道具有特定原型的函数存在就足够了(异常:内联函数!)。然后,编译器可以生成执行函数调用所需的所有代码,但函数的实际地址除外,因为它保留了某种占位符
然后链接器将编译步骤中生成的所有代码合并到一个单元中。由于现在知道每个函数的位置,它可以将它们的实际地址填入占位符中,无论它们出现在哪里。C++代码被编译成*.obj
for per.cpp
文件,正是链接
过程使obj文件成为可执行文件
切勿包含*.cpp,因为它通常会导致重新定义问题
对于每个*.h文件,添加一个宏以避免出现多个错误,包括:
#ifndef XXX_H
#define XXX_H
//your code goes here
#endif
它使类的定义可用。实际实现是在链接时解决的,因为ClassA.o和ClassB.oI不太了解您的情况。您将ClassA.h
和ClassB.h
都包括在哪里?在main.cpp
中?还有,是什么让你认为它会让实际代码出现?在C++中,一个包含引用的指令只是当前文件内部文件内容的复制粘贴。通常,您应该只包含.h文件,而不是在.cpp中复制编译后的代码