我为什么不把所有东西放在标题中?

Kol*_*dar 0 c++

我开始使用C++,我来自C和Java.我知道在C中强烈建议在源代码的头和变量/类型/函数定义中编写变量/类型/函数声明; 所以,当我开始使用C++进行编码时,我认为也遵循相同的约定.

对我来说不幸的是,在C++中,此规则有几个例外,其中包括:

  • 模板类;
  • 内联函数;
  • constexpr功能;

这让我对文件产生了一些困惑:它们中的大多数是*.cpp包含少量中/大成员函数的文件的标题.

所以我的问题是:假设只使用类进行编码,而不是使用普通的C,为什么我不能只将所有内容放在标题中并且没有cpp文件?(有点Java风格); 澄清:我将主要处理类,模板类,最多模板函数.

例如Foo.hpp:

class Foo {
public:
 foo() {
     //body
 }
 bar() {
     //body
 }
}
Run Code Online (Sandbox Code Playgroud)

而不是在*.hpp和之间划分*.cpp:

//file Foo.hpp
class Foo {
public:
 foo();
 bar();
}

//file Foo.cpp
Foo::foo() {
   //body
}
Foo::bar() {
   //body
}
Run Code Online (Sandbox Code Playgroud)

当然会放入类似静态全局变量的东西.*cpp,但是根据我的理解,它们是唯一需要放入cpps的东西(并且强烈建议不要使用它们).

你能否告诉我这种方法有哪些缺点?作为C++的初学者,我肯定会忽略一些重要的因素.在我天真的观点中,没有什么需要在cpp文件中(假设我只编写类当然).

谢谢

eer*_*ika 5

为什么我不能把所有内容放在标题中并且没有cpp文件?

好吧,你必须至少有一个源文件,否则你没有任何东西可以编译.

但是,要回答,为什么不把所有内容放在一个源文件中:因为源文件的大小线性增加到整个程序的大小(拆分成头文件不会减小大小.相关的是预处理后的尺寸).因此(重新)编译它变得越来越慢,并且对该源文件的任何部分(即整个程序的任何部分,也包括所包含的头部)的任何更改都要求您重新编译该源文件(即整个计划)再次.

如果将程序拆分为多个源文件,则只需要重新编译那些已修改的源文件.对于大型项目,这可以将一小时的编译减少到一分钟,这在典型的工作流程是"编辑 - >编译 - >调试 - >编辑 - >编译 - > ..."时是一个福音.

动态链接可以进一步发挥这一优势:即使没有重新链接,您也可以简单地替换动态库(只要新版本与ABI兼容).


为了公平起见,我还要回答为什么要将所有内容放在单个源文件中:因为它可以从头开始减少编译时间.如果您的工作流程不能与增量重构一起使用,那么减少完整的编译时间会比没有更好.并且因为它允许更好的优化,因为编译器不能跨源文件进行内联扩展(链接时优化可能会降低此优势,如果您可以依赖它可用).


理想的解决方案可能既不是在单个大型源文件中定义所有函数,也不是在每个单独的源文件中定义所有函数的理想选择.理想的选择可能介于两者之间.

典型的约定是为每个类的成员函数提供单个源文件,但是没有绝对的理由应该遵循此约定.在单个源文件中定义多个类的成员函数是完全没问题的,并且可以很好地将一个类的定义成员函数划分为单独的文件,只要您有这样做的参数即可.


我认为这种方法会"方便",因为你停止寻找一个函数:它在cpp文件中; 该死的不是:它是一个模板所以它在标题中...这非常令人沮丧!

与编译时间考虑相比,这不是一个强有力的论据.开发环境是可用的(即使是免费的,已经持续了几十年),它允许您在几分之一秒内跳转到函数声明(或调用)的定义.