编译cpp时不使用相应的头

Compile cpp without corresponding header

本文关键字:cpp 编译      更新时间:2023-10-16

在阅读了一些学习C++语言的书籍后,我刚刚收到了第一个真正的C++应用程序。据我所知,您的cpp源文件需要cooresponsing标头,但我的项目中的一个库使用了许多不包括cooresponsing头的cpp文件,构建得很好。这个特殊的cpp实现了一个在头中找到的类,该类具有不同的名称和许多其他代码,而不仅仅是原始类声明。

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

这些函数的实现是否可以独立编译,并在使用库的客户端应用程序(包括带有类声明的头)调用相应的成员函数时简单地调用?如果是这种情况,客户端应用程序如何引用实现二进制文件?(我想这是链接器……但我很想把它清理干净)。

我预计这个答案可能会暴露出我对包含和编译过程的误解,我真的很想好好学习C++的这方面。非常感谢。

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

您将能够在任何包含类声明的源文件中定义类中的任何函数,这是源文件"了解"类/函数的情况。

也不要求头文件和源文件的内容有任何关系。然而,人们普遍认为这是一种非常好的做法。

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

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

以下是几个问题。你应该试着把这些分开。

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

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