2012-03-27 55 views
0

我刚刚通过学习该语言的书籍完成了第一个真正的C++应用程序的工作。 这是我的理解,你的CPP源文件需要cooresponding头,但我的项目中的库之一是建立罚款与许多CPP文件,不包括cooresponding头。这个特殊的cpp实现了一个头部中的类,该头部具有不同于原始类声明的不同名称和数量的其他代码。编译没有相应头文件的cpp

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

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

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

+1

头文件只是在文本上包含在翻译单元中。没有魔法。相反,头文件是20世纪70年代令人惊叹的原始文件。你根本不需要头文件,不是认真对待这个想法的好主意。如果您有一个翻译单元不向系统中的其他参与者提供任何功能,那么就不需要标题。一个很好的例子是一个包含你的'main'函数的小型翻译单元。 – 2012-03-27 17:08:04

+0

看看这个SO qn关于编译和链接:http://stackoverflow.com/questions/6264249/how-does-the-compilation-linking-process-work – Sanish 2012-03-27 17:11:59

回答

2

当编译C++源文件时,它的第一个阶段是预处理。 当include指令到达时,找到文件和文件的全部内容,无论它是否包含在源文件中,就好像它已经写入源文件本身一样。

您将能够在包括类的声明任何源文件中的类定义的任何功能,这是源文件“知道”关于类/功能”。

还有不要求头文件和源文件的内容有任何关系,但被广泛认为是非常好的做法

每个编译单元(源文件)的实现是独立编译的,任何函数定义都可以放在任何编制单位,这并没有什么不同,当编制单位联系在一起时,每个宣言的用法都与所有定义。

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

0

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

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

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