简体   繁体   中英

Coding best practices

Is it a good programming practice to have #include statements in a header file. I personally feel that, especially, when you're going through a code base someone else wrote, you end up missing or spend time looking for definitions which could have found sooner if it was in the c file.

In some (from my experience - most ) cases, it's impossible to do what you say. You often end up returning various other classes from your code, and - obviously - you need to include the information about that in the function declarations. In that case, the compiller has to already know what those other objects are, so you either have to already include a header with the declaration, or provide a forward declaration.

Since you'll end up including the header anyhow, there's no real point in doing an additional forward declaration. That's of course a thing of choice, but it doesn't make your code clearer in my opinion.

Also - most of the IDE's have an option to find a symbol in the included files.

If (and only if ) you're in a point when you only need classes/functions inside your definitions, then you may vote to include the header in the *.c file. It may be clear at first glance, but you may find that - when modifying the class someday - you'll end up moving the #include to the *.h file anyway.

The short answer is yes. If a particular header that is defining/declaring classes, types, structs, etc. that are composed of classes, types, structs, etc. that are defined/declared in other header files then the most expedient and effective practice is to include those header files into the header file.

By doing so, the header files that are dependencies on the header file you are creating will be there.

There may be issues of files being included multiple times which is why most header files contain either #if to ensure the file is included only once or using something like a #pragma to ensure only included once.

To sum up, you should design your header files so that if they are included multiple times by several uses of a #include of your header file that the header file will only appear once in the preprocessor output. By including the header files on which your header file depends in the header file, you localize the use of the header and make sure that any dependencies will be available.

And in addition by using the #include of dependency header files into your header file, if the include path is incorrect so that a dependency header file is not available, it will be easy to find the header which is depending on the unavailable header file.

Header files should manage their own dependencies; having to get the order of #include s in a .c file just right is an annoying way to waste an afternoon, and it will be a perpetual maintenance headache going forward. Have you headers #include whatever they need directly, use #include guards in your own headers, and life will be much easier.

It is not in bad style if it is necessary to make the header file self-contained in the sense that it does not depend on any other header being manually included. For example, if the header contains declarations that use data types from stdint.h then it should have #include <stdint.h> rather than expect everyone to include it separately, and in the correct order.

Meanwhile unnecessary #include s are generally in bad style regardless of where they are ( .h or .c ). Arguably an exception to this might be an entire collection of libraries that could in theory be used individually but are intended to be used as a whole, such as a complete GUI toolkit – in that case I think it's cleaner to have some master header that pulls in all the declarations rather than have the user learn which header is required for which specific function.

I prefer to not have #include in header files, if only to make the dependencies visible on one place for each source file. But that is certainly arguable.

Golden rule is readability . Silver rule is follow existing practice .

Don't #include anything you don't need.

Don't #include anything you don't need because including unnecessary files leads to unnecessary dependencies and also leads to larger compile times for larger projects. As a consequence, if you modified an existing class to replace vector with list , take an extra few seconds to look through the file and make sure you don't have any vector remnants left over, and delete the #include <vector> from the top of the file.

Use forward declarations instead of #include where possible.

Use forward declarations where possible because it reduces dependencies and minimizes compile times. A forward declaration will do if your class header does not declare an object of the class; if you only use it by pointer or (in C++) by reference, then you can get by with a forward declaration.

Use #ifdef or #pragma guards to design your header files such that they're not included multiple times.

// MyClass.h

#ifndef MYCLASS_HEADER
#define MYCLASS_HEADER

// [header declaration]

#endif // MYCLASS_HEADER

Alternatively on a supporting compiler such as Visual Studio:

// MyClass.h

#pragma once

// [header declaration]

These guards will allow you to #include "MyClass.h" as often as desired without worrying about including it multiple times in the same translation unit.

Include/forward-declare in the header if the included file is needed by the header.

If the header needs a forward declaration or to fully include the header, then doing so is a no-brainer.

Include in the .c/.cpp file if the included file is not needed by the header, but is needed by the implementation.

If the header has no use for the header--because a forward-declaration is sufficient or because only the .c/.cpp file needs it--then don't #include in the header. Remember: Push off whatever you can into the .c/.cpp file to reduce dependencies and minimize compile times.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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