C++ 为什么包含.h也会使.cpp源与它一起出现?

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”;但这样做只

我是一个有经验的程序员,但只会高级语言;我现在正在做我的第一个真正的C++大型工程。 我有两门课,
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中复制编译后的代码