为什么我们包含头文件而不是源文件?

我已经看到有人问过类似的问题,但它们对我的猿类大脑仍然没有意义。

这是一个例子。如果我在名为Bob.h:的头文件中声明了一个函数void PrintSomething();,在该.cpp文件中我说:void MyClass::PrintSomething(){std::cout << "Hello";}. .cpp例如Frank.cpp,我在另一个文件中看到人们,只包含Bob.h只有声明的标题(其中没有代码),而不.cpp包含代码,但是当他们调用其中的PrintSomething()函数Frank.cpp使用代码时,让我大吃一惊的是Bob.cpp并打印“你好”。如何?.cpp当我只包含一个.h没有说明“Hello”的文件时,它如何打印添加到文件中的“Hello”,它只是一个声明?我也查看了编译过程和链接过程,但它只是不坚持。

最重要的是,如果我现在在我的Frank.cpp文件中说:void MyClass::PrintSomething(){std::cout << "Bye";}并将文件包含Bob.h在我的文件中main.cpp并调用该PrintSomething()函数,它会打印“Hello”还是“Bye”?是电脑通灵还是什么?这个概念是我在 C++ 学习之旅中没有掌握的一件事。

提前致谢。

回答

当你包含Bob.h编译器时PrintSomething(),它拥有了它需要知道的一切,它只需要一个函数声明。Frank.cpp不需要知道Bob.cpp哪个定义PrintSomething()

您所有的单个cpp文件输出编译器生成的目标文件。在它们全部粘合在一起之前,它们本身不会做太多事情,这是链接器的责任。

链接器获取您所有的目标文件并填充缺失的部分:

链接器谈话:

嘿,我看到它在Frank.obj使用PrintSomething(),但在那个目标文件中我看不到它的定义。

让我们检查其他目标文件..

检查后Bob.obj我可以看到这包含一个可用的定义PrintSomething(),让我们使用它。

这当然是简化的,但简而言之,这就是链接器所做的。

完成此操作后,您将获得可用的可执行文件。


最重要的是,如果我现在在我的 Frank.cpp 文件中说:void MyClass::PrintSomething(){std::cout << "Bye";}并将文件包含Bob.h
在我的main.cpp和调用的PrintSomething()函数中,它会打印“Hello”还是“Bye”?是电脑通灵还是什么?

链接器会找到 2 个定义PrintSomething()并发出错误,它无法知道选择哪个定义是正确的。


以上是为什么我们包含头文件而不是源文件?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>