When should I not split my code into header and so

2019-06-21 14:19发布

I know this maybe quite subjective, but are there any general rules for situations when it is not necessary for code to be split into two files?

For example is the class is extremely small, or if the file simply holds some global definitions or static functions? Also, in these cases, should the single file be a .cpp file or a .h file?

5条回答
趁早两清
2楼-- · 2019-06-21 14:52

I know this maybe quite subjective, but are there any general rules for situations when it is not necessary for code to be split into two files?

Split the code into header and source whenever you can.

Generally, this shouldn't be done in next cases :

  • the code consists of template classes and functions (unless you explicitly instantiate templates in the source file)
  • the header consists only of inline functions

should the single file be a .cpp file or a .h file?

Should be the header file (.h).

查看更多
干净又极端
3楼-- · 2019-06-21 14:57

I favor putting code in .hpp files but am very often compelled to put the implementation in the .cpp for any of the following reasons:

  1. Reducing build time. This is the #1 reason to use .cpp files... and the reason most code you find in .hpp files is small and simple. When the implementation changes, you don't want to have to rebuild every .cpp that includes it.
  2. When the function's linkage is important. For example, if the function is exported as a library (e.g. DLL) function, it's important that it select a single compilation unit to live in. Or for static / global instances. This is also important for distributing an import header for a DLL.
  3. When you wish to hide implementation details when distributing a library
  4. The definition and declaration are not identical. This can be the case with respect to constness of arguments.
  5. You want a "clean" overview of the interface in the .hpp file. I find that with modern code tools and increasing familiarity with single-code-file languages like javascript / C# / inline C++, this is not a strong argument.
  6. You explicitly do not want the function to be declared inline. Although, it won't matter; the optimizing compiler will likely inline if it wants to.

There are logical motivations for keeping code inline in a .hpp file:

  1. Why have two files when you can have one?
  2. Duplicating the declaration / function headers is unnecessary maintenance and feels redundant. We have code analysis tools to show interfaces.
  3. The concept that inline / template code must be put in a header and other code is put in a .cpp is arbitrary. If we are forced to put inline code in a .hpp file, and this is OK, then why not put all code in a .hpp file?

I am pretty sure though that the tradition of separate .cpp and .hpp files is far stronger than the reasoning however.

查看更多
可以哭但决不认输i
4楼-- · 2019-06-21 15:04

The rule I use is the following:

Whenever you can put code into a cpp file, do it.

The reasons are multiple:

  • Header files serve as rudimentary documentation. It is better not to clutter them with code.
  • You can also use pimpls at some places if you feel like, for the reason above.
  • It reduces compilation times:
    • whenever you change a .cpp, only this file will be recompiled.
    • whenever a header is included, it only contains the minimal amount of code needed
  • It allows you to assess more easily which part of your code depends on which other part, just by looking at which headers are included. This point mandates another rule of mine:

Whenever you can forward declare a class instead of including a header, do it.

This way, the .cpp files carry the dependency information between parts of your source. It also lowers build times.

查看更多
We Are One
5楼-- · 2019-06-21 15:06

On the technical side, whenever you need to obey the one definition rule you have to separate declarations from definitions, since you will need to include the declarations many times in multiple translation units, but you must only provide one single definition.

In aesthetic terms, the answer could be something like "always", or "systematically". In any case, you should always have a header for every logical unit of code (e.g. one class or one collection of functions); and the source file is one that is possibly optional, depending on whether or not you have everything defined inline (exempting you from ODR), or if you have a template library.

As a meta strategy, you should seek to decouple the compilation units as much as possible, so that you can include only what's needed in a fine-grained way. This allows your project to grow without having compilation times become unbearable, and it makes it much easier to reuse code in other projects.

查看更多
地球回转人心会变
6楼-- · 2019-06-21 15:14

I know this maybe quite subjective, but are there any general rules for situations when it is not necessary for code to be split into two files?

It's not always subjective; you will very good reasons to separate them in large projects. It's good to get into the practice of separating them, and learning when it is and is not appropriate to separate definition from declaration. It's hard to answer your question without knowing how complex your codebase will become.

For example is the class is extremely small

It's still not necessarily a bad idea to separate them, in general.

or if the file simply holds some global definitions

The header should not contain global definitions which require static construction, unless necessary.

or static functions?

These do not belong anywhere in C++. Use inline, or anonymous namespace. If you mean within a class' body, "it depends on the instruction count, if you are hoping it will be inlined".

Also, in these cases, should the single file be a .cpp file or a .h file?

The single file should be a header. Rationale: You should not #include cpp files.

And don't forget that intermodule (aka link-time) optimizations are getting better and better.

C++ compilation times are long, and it's very very very time consuming to fix this after the fact. I recommend that you get into the practice of using cpp files before your build times and dependencies explode.

查看更多
登录 后发表回答