编译没有相应标头的cpp

时间:2012-03-27 16:51:58

标签: c++ build compilation linker include

在完成学习语言的一些书之后,我刚刚在工作中获得了我的第一个真正的C ++应用程序。 我的理解是你的cpp源文件需要相应的头部,但是我的项目中的一个库正在使用许多不包含cooresponding头的cpp文件构建正常。这个特殊的cpp实现了一个在头文件中找到的类,它具有不同的名称和许多其他代码片段,而不仅仅是原始的类声明。

cpp如何编译属于它不知道的类的函数?

这些函数的实现是否可以独立编译,并且在使用库的客户端应用程序(包括带有类声明的头文件)调用相应的成员函数时可以简单地调用它们?如果是这种情况,客户端应用程序如何引用实现二进制文件? (我假设这是链接器...但我希望能够清除它。)

我预计答案可能会引发我对包含和编译过程的误解,我真的很想学习C ++的这个方面。谢谢!

2 个答案:

答案 0 :(得分:2)

编译c ++源文件时,它经历的第一个阶段是预处理。 当达到include伪指令时,找到该文件,并且该文件的全部内容(包括源文件中包含的内容)就好像它已经写入源文件本身一样。

您将能够在包含类声明的任何源文件中定义类中的任何函数,这是源文件“知道”类/函数“。

也不要求标题和源文件的内容有任何关系。然而,它被广泛认为是非常好的做法。

每个编译单元(源文件)的实现都是独立编译的。任何函数定义都可以放在任何编译单元中,它不会产生任何差别。当编译单元链接在一起时,每个声明的用法都与所有定义相匹配。

除了源文件和头文件(我能想到的)之间的1:1关系之外,有些人可能使用的唯一其他模式是每个头文件描述一个类,每个源文件将实现一个集合相关功能。但这是一个坏主意(在我看来),因为它会鼓励各种类的定义,因为高度耦合。

答案 1 :(得分:0)

这些是几个问题。你应该尝试拆分这些。

  1. 声明某些内容的文件的名称不是相关的。编译器将预处理器输出独立于预处理器读取的文件。编译器可能使用预处理文件中的某些文件/行信息来发出更可读的诊断消息。 当您在头文件中声明一个类并将该声明复制到实现文件时,只要您不更改声明的其中一个副本,一切正常。这是危险的,应该避免。一直宣告任何事情。

  2. 编译类成员函数的实现时,您将获得一个链接器可以链接到客户端程序的函数。一个好的工具链只能链接访问的功能。因此,您可以将接口(在头文件中)与静态库中提供的实现分开。链接器会将库中的每个对象模块添加到可执行文件中,直到解析完所有符号引用。