将类划分为定义和实现不是纯粹为了编译时的目的吗

Is dividing classes into defintion and implementation not purely for compile time purposes?

本文关键字:编译 纯粹 划分 定义 实现      更新时间:2023-10-16

我经常发现在头文件和实现文件中定义东西会更麻烦,而在头文件中编写实现也很好。通常这样做的原因是什么?

实际原因:减少编译时间,有助于编译器,能够将接口与实现分离,从而创建共享/动态库,这些库可以换成不同的版本,而无需重新编译原始程序。

实际原因:常识。

单独编译是一个很大的问题。当您有数百到数千个cpp文件时,时间开始累积。如果所有内容都只是在头中实现的,那么每次单个类更改任何内容时,都必须进行完全的重新编译。

另一个是设计/文档视角。类的用户应该能够以简洁的方式从头文件中获得他们需要的所有信息,而不必查看实现。

从简单的管理角度来看,像这样将接口与实现分离可能(而且通常)非常有用(尤其是在大型项目中)。

编写指定接口的头,项目的其他部分可以像该组件已经完成一样编写,即使它还没有真正实现。在典型的情况下,您可能会编写一个标头,然后在稍后编写一个琐碎的模拟实现(例如,它只是返回说操作失败,而实际上没有做任何事情),然后在以后仍然编写一个真正的实现,尝试做任何有用的事情。

显然,在您至少有一个mock实现之前,代码不会链接,但代码的其他部分至少可以只使用头进行编译。

你是对的,它很麻烦,而且现在显然有将所有内容都放入头文件的趋势,这可能是因为人们使用Java和C#等语言,在这些语言中,你可以在一个位置声明和实现。

然而,C++编译模型远比这些语言复杂,#include的本质意味着编译器必须打开、预处理和解析包含的每个文件。这对一个大型项目来说可能是一个巨大的打击。由于方法的实现往往比类的声明更容易发生变化,因此要最大限度地减少重新编译的工作量,编译器必须这样做——您可以更改方法。通过将代码放入.cpp文件,它只需要重新编译即可。如果您将其放入标头中,则必须重新生成包含该标头的每个文件。

如果在开发过程中将新方法添加到类中,则不可避免地会遭受重建的打击。但是,如果使用pimpl(不透明指针)模式添加成员变量,则可以避免受到影响。