繁体   English   中英

为什么在C ++中将类声明和定义放在两个单独的文件中?

[英]Why put a class declaration and definition in two separate files in C++?

我只是想知道,将类分成.h和.cpp文件的重点是什么? 它使编辑变得更加困难,如果您的类不会被编译成.lib或.dll以供外部使用,那有什么意义呢?

编辑:我问的原因是Boost库将所有内容都放在.hpp文件中(大多数库仍然是这样),我想知道为什么它在我看到的大多数其他代码中都是分开的。

C ++有一个叫做One Definition Rule的东西。 这意味着(不包括内联函数),定义只能出现在一个编译单元中。 由于C ++头文件只是在每个包含文件中“复制并粘贴”,所以如果只是将定义放在头文件中,那么现在要将定义放在多个位置。

当然,你可能会说,为什么不把一切都内联。 好吧,如果编译器尊重你的内联建议,长函数的代码将在每个调用站点复制,使你的代码过大,并可能导致颠簸,缓存问题和各种未完成的东西。

另一方面,如果编译器不听你的话,并且没有内联任何内容,那么现在你有两个问题:1)你不知道哪个翻译单元得到你的类定义,2)编译器仍然需要每次#include他们时都会浏览你的定义。 此外,没有简单的方法可以确保您不会在两个不同的标题中两次意外地定义相同的方法,这是不同的。

您还会遇到循环依赖问题。 对于要调用另一个类的方法的类,需要首先声明该类。 因此,如果2个类需要调用彼此的方法,则必须先声明每个类,然后才能定义它们。 在一个文件中无法使用声明和定义执行此操作。

真的,这是语言和解析器的构建方式。 这是一种痛苦,但你只需要处理它。

那么,以这种方式使用代码的好处之一是它减少了编译时间。

假设您的项目中包含以下文件:

  • a.cpp
  • b.cpp

如果你已经有a.cpp编译成目标文件AO,那么如果您在b.cpp ,编制应该是更快,因为解析器将不必处理整个声明/定义。

Boost没有内联所有代码; 它为其期望消费者实例化的类内联模板定义,如shared_ptr。 许多库都有需要单独编译的部分,比如boost :: serialization和program_options。

随着代码库大小的增加,内联可能会产生严重的负面影响。 它增加了组件之间的耦合,更不用说编译你的编译时间了(由于其他很多原因,这种情况有所提升:)。 实际上,您的所有翻译单元几乎都有一个完整的程序副本,一个微小的变化将导致您重建/重新测试所有内容。 在某些项目中,这可能需要很多小时。

我从来没有真正注意到编辑更难; 根据我的经验,由于界面和实现的明确分离,它使得它变得更容易,并且我知道要找到我正在寻找的文件。

因为即使在你的DLL中,其他类也会使用你的类。 这些文件必须在编译时通过包含.h来查看类声明。 他们不能看到定义,或者会有多个类函数的定义。

你的编辑:Boost是一个重要的区别。 由于编译器和链接器在当前C ++标准中的工作方式,模板类几乎总是在头文件中定义。 您会发现大多数模板库(不仅仅是Boost)都是在头文件中实现的,原因相同。

在C ++中,单独编译代码模块(.c或.cpp文件)需要在使用之前定义函数原型。 如果要使用其他位置定义的类或方法,则必须导入.h文件以获取其定义。 最后,链接器确保所有c / cpp文件都能满足.h文件中的所有promise。

此外,它允许仅通过定义.h文件来创建整个框架,例如boost。

因为在大多数情况下,除了实现它的文件之外,您还希望使用该类。 如果将整个程序放在一个文件中,则不需要分离。

你几乎不想在一个文件中编写C ++程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM