为什么我不应该将所有内容都放在标题中? [英] Why shouldn't I put everything in header?

查看:49
本文介绍了为什么我不应该将所有内容都放在标题中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始使用C ++,并且来自C和Java.我知道在C语言中强烈建议在标头中编写变量/类型/函数声明,并在源代码中编写变量/类型/函数定义.因此,当我开始使用C ++进行编码时,我也想遵循相同的约定.

I'm starting to work with C++ and I come from C and Java. I know that in C is strongly advisable to write variable/types/function declarations in the header and variable/types/function definitions in the source code; so when I started coding in C++ I thought to adhere to the same convention as well.

不幸的是,在C ++中,该规则有几个例外:

Unluckly for me, in C++ there are several exceptions to this rule, among the others:

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

这使我对文件有些困惑:它们中的大多数是带有 *.cpp 文件的标头,其中包含很少的中/大型成员函数.

This lead me to some confusion in the files: most of them are headers with *.cpp files containing few medium/big member functions.

所以我的问题是:假设仅使用类而不是使用普通C进行编码,为什么我不能只将所有内容放在头文件中并且没有cpp文件?(某种Java样式);需要说明的是:我最多将不得不处理类,模板类,最多只能处理模板功能.

So my question is: assuming to code only with classes, not with plain C, why can't I just put everything in the header and have no cpp files? (sort of Java style); to clarify: I will mostly have to deal with classes, template classes, at most template functions.

例如在 Foo.hpp 中:

class Foo {
public:
 foo() {
     //body
 }
 bar() {
     //body
 }
}

而不是在 *.hpp *.cpp 之间进行分隔:

instead of having the division between *.hpp and *.cpp:

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

//file Foo.cpp
Foo::foo() {
   //body
}
Foo::bar() {
   //body
}

当然会在.* cpp 中放入诸如静态全局变量之类的东西,但是据我所知,它们是唯一需要放入cpps中的东西(并且强烈建议不要使用它们.

Of course something like static global variables will be put in .*cpp, but for my understanding they are the only thing that is required to be put in cpps (and their use is strongly discouraged as well).

能否请您告诉我这种方法的弱点是什么?作为C ++的初学者,我肯定会忽略一些重要因素.在我幼稚的观点中,cpp文件中不需要任何内容​​(假设我当然仅使用类进行编码).

Can you please tell me what are the weaknesses of this approach? Being a beginner in C++ I'm sure to have ignore some important factor. In my naive view, there is nothing that requires to be in the cpp files (assuming that I'm coding only with classes of course).

谢谢

推荐答案

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

why can't I just put everything in the header and have no cpp files?

好吧,您必须至少有一个源文件,否则就没有什么要编译的.

Well, you must have at least one source file, or else you have nothing to compile.

但是,要回答,为什么不应该将所有内容都放在单个源文件中:因为该源文件的大小线性增加到整个程序的大小(拆分为头文件确实会不减小尺寸.相关的是预处理后的尺寸.因此,(重新)编译它的速度越来越慢,并且对该源文件的任何部分(即整个程序的任何部分,还包括标头)进行的任何更改都要求您重新编译该源文件(即整个程序).

But, to answer, why shouldn't you put everything in a single source file: Because the size of that source file increases linearly to the size of the entire program (splitting into header files does not reduce the size. What is relevant is the size after pre-processing). And therefore (re-)compiling it becomes increasingly slower, and any change to any part of that source file (i.e. any part of the entire program, also the headers that are included) requires you to re-compile that source file (i.e. the entire program) again.

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

If you split the program into multiple source files, only those source files which are modified need to be re-compiled. For big projects, this can reduce an hour of compilation to a minute, which is a boon when the typical workflow is "edit -> compile -> debug -> edit -> compile -> ...".

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

Dynamic linking can further this advantage: You can simply replace a dynamic library even without re-linking (as long as the new version is ABI compatible).

为了公平起见,我还要回答为什么应该将所有内容都放在单个源文件中:因为这会减少从头开始的编译时间.如果您的工作流程不适用于增量重建,那么稍微减少整个编译时间总比没有好.并且由于它可以提供更好的优化,因为编译器无法在源文件之间进行内联扩展(如果可以依靠链接时间优化,则链接时间优化可能会降低这一优势).

For fairness, let me also answer why should you put everything in a single source file: Because it reduces the compilation time from scratch. If your workflow doesn't work with incremental re-builds, then reducing the full compilation time a bit is better than nothing. And because it allows better optimization, because a compiler cannot do inline expansion across source files (link time optimization may reduce this advantage, if you can rely on it being available).

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

Ideal solution is probably neither to define all functions in a single massive source file, nor is it ideal to define all functions in separate source files each. Ideal option is probably somewhere in between.

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

A typical convention is to have a single source file for member functions of each class, but there is no absolute reason why this convention should be followed. It is completely fine to define member functions of multiple classes in a single source file, and also fine to divide definitions member functions of one class into separate files, as long as you have an argument for doing so.

我认为这种方法将是方便的",因为您不再寻找函数:它位于cpp文件中;该死的:这是一个模板,所以它在标题中……非常令人沮丧!

I thought this approach would be "convenient" because you stop looking for a function: it was in a cpp file; damn not: it was a template so it was in the header... it's pretty frustrating!

与编译时间考虑因素相比,这不是一个有力的论据.开发环境可用(甚至是免费的,并且已经使用了数十年),使您可以在不到一秒钟的时间内跳转到函数声明(或调用)的定义.

This is not a strong argument compared to compile time considerations. Development environments are available (even for free, and have been for decades) which allow you to jump to the definition of a function declaration (or invocation) in a fraction of a second.

这篇关于为什么我不应该将所有内容都放在标题中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆