1

我不知何故无法抓住这个想法,阅读文档对我没有帮助。

我的问题是:

  1. 当我包含一个头文件#include“general.h”时,在我的项目目录中有两个文件general.h和general.cpp,是否意味着我的预编译器会自动找到.cpp文件?
  2. 我可以包含没有扩展名的文件:#include “general”吗?
  3. 我可以包含一个没有任何头文件的文件:#include “general.cpp”吗?
  4. 我可以包含一个 txt 文件:#include "general.txt" 吗?

我在 Visual Studio 2010 中尝试了这一切。至少没有语法错误。但我想有个解释。所以,我希望你能善待我并帮助我。

4

5 回答 5

6

标准和编译器并不真正关心文件是.cppor.h还是.monkeyface. 将源代码结构化为实现和头文件背后的概念实际上只是帮助管理源代码的公认方法。尽管如此,不以公认的方式构建源代码通常被认为是不正确或糟糕的 C++。

所做的只是告诉预处理器将您指定的文件的内容包含在#include当前文件中。这就像将其他文件复制并粘贴到您的文件中一样。当您说#include "foo.h"时,它只包含 的内容foo.h并且根本不关心foo.cpp- 它甚至不知道它存在(并且没有理由必须存在)。

在实现和头文件中构建源代码非常有用 - 它避免了依赖项和多个定义的问题,并且还可以在一定程度上缩短编译时间。当您的代码使用另一个类时,您只需要该类#include的头文件。原因是您的代码不需要关心类的实现,它只需要知道它的样子(它的名称、成员、基类等)。它不关心成员函数是如何实现的。

扩展.cpp.h仅仅是约定。有些人喜欢使用.hpp头文件。有些人甚至使用.tpp模板实现。您可以随意命名它们 - 是的,您甚至可以包含一个.txt文件。您的编译器可能会尝试从文件扩展名推断有关文件的内容(例如,将其编译为哪种语言),但这通常是可覆盖的。

因此,如果您main.cpp包含foo.h因为它使用 class foo,那么在什么时候foo.cpp参与?好吧,在编译中main.cpp,它根本不涉及。main.cpp不需要知道类的实现,就像我们上面讨论的那样。但是,在编译整个程序时,您会将每个.cpp文件传递给编译器以单独编译。也就是说,你会做类似的事情g++ main.cpp foo.cpp。编译时foo.cpp,它将包含需要编译的头文件。

在您的每个.cpp文件都被编译后(包括包括它们所依赖的头文件),然后将它们链接在一起。在这个阶段,成员函数的使用foo::bar()main.cpp与 中foo::bar()给出的实现相关联foo.cpp

于 2013-01-17T17:54:50.337 回答
1

#include指令告诉预处理器读取文件。就这样。

于 2013-01-17T17:45:49.463 回答
1

预处理器在遇到#include 指令时简单地插入给定文件的全部内容。

于 2013-01-17T17:46:51.443 回答
0
  1. 不,预编译器对 .cpp 文件一无所知

  2. 是,如果文件没有扩展名

  3. 您可以包含任何您想要的文件。这并不意味着你会从中得到任何有用的东西。

  4. 见上文第 3 点。

于 2013-01-17T17:46:58.853 回答
0

#include是一个简单的“在此处插入给定文件的内容”机制,因此预处理器将完全包含您指定的文件。如果包含 .h 文件,预处理器和编译器都不会知道相应的 .cpp 文件 - 每个 .cpp 文件都是单独编译的(.h 文件的目的是告知编译器哪些函数存在于当前的 .cpp 文件)。编译后,调用链接器,然后将不同.cpp文件的编译结果合并。

于 2013-01-17T17:54:52.383 回答