Is there a standard #include convention for C++?

前端 未结 8 1796
隐瞒了意图╮
隐瞒了意图╮ 2021-01-01 16:49

This is a rather basic question, but it\'s one that\'s bugged me for awhile.

My project has a bunch of .cpp (Implementation) and .hpp (Definition) files.

I f

相关标签:
8条回答
  • 2021-01-01 17:22

    Some best practices:

    • Every .cpp or .C file includes all headers it needs and does not rely on headers including other related headers
    • Every .hpp or .h file includes all its dependencies and does not rely on the included headers including other related headers
    • Every header is wrapped with:

      #ifndef HEADER_XXX_INCLUDED
      #define HEADER_XXX_INCLUDED
      ...
      #endif /* HEADER_XXX_INCLUDED */
      
    • Headers do not include each others in cycles

    • Often: there is a single "project-wide header file" like "config.h" or ".h" which is always included first by any .cpp or .C file. Typically this has platform related configuration data, project-wide constants and macros etc.

    These are not necessarily "best practice", but rules which I usually follow also:

    • Project-specific headers are included as #include "..." and before the system-wide headers, which are included as #include <...>
    • Project-specific headers are included in alphabetical order as a way to ensure that there is no accidental, hidden requirement on which order they are included. As every header should include its dependents and the headers should be protected against multiple inclusion, you should be able to include them in any order you wish.
    0 讨论(0)
  • 2021-01-01 17:23

    Check out John Lakos's Large-Scale C++ Software Design. Here's what I follow (written as an example):

    Interface

    // foo.h
    // 1) standard include guards.  DO NOT prefix with underscores.
    #ifndef PROJECT_FOO_H
    #define PROJECT_FOO_H
    
    // 2) include all dependencies necessary for compilation
    #include <vector>
    
    // 3) prefer forward declaration to #include
    class Bar;
    class Baz;
    #include <iosfwd> // this STL way to forward-declare istream, ostream
    
    class Foo { ... };
    #endif
    

    Implementation

    // foo.cxx
    // 1) precompiled header, if your build environment supports it
    #include "stdafx.h"
    
    // 2) always include your own header file first
    #include "foo.h"
    
    // 3) include other project-local dependencies
    #include "bar.h"
    #include "baz.h"
    
    // 4) include third-party dependencies
    #include <mysql.h>
    #include <dlfcn.h>
    #include <boost/lexical_cast.hpp>
    #include <iostream>
    

    Precompiled Header

    // stdafx.h
    // 1) make this easy to disable, for testing
    #ifdef USE_PCH
    
    // 2) include all third-party dendencies.  Do not reference any project-local headers.
    #include <mysql.h>
    #include <dlfcn.h>
    #include <boost/lexical_cast.hpp>
    #include <iosfwd>
    #include <iostream>
    #include <vector>
    #endif
    
    0 讨论(0)
  • 2021-01-01 17:27

    Building on what antti.huima said:

    Let's say you have classes A, B, and C. A depends on (includes) B, and both A and B depend on C. One day you discover you no longer need to include C in A, because B does it for you, and so you remove that #include statement.

    Now what happens if at some point in the future you update B to no longer use C? All of a sudden A is broken for no good reason.

    0 讨论(0)
  • 2021-01-01 17:33

    Organizing code files in C and C++:

    0 讨论(0)
  • 2021-01-01 17:38

    There are several problems with the #include model used in C/C++, the main one being that it doesn't express the actual dependency graph. Instead it just concatenates a bunch of definitions in a certain order, often resulting in definitions coming in a different order in each source file.

    In general, the include file hierarchy of your software is something you need to know in the same way as you know your datastructures; you have to know which files are included from where. Read your source code, know which files are high up in the hierarchy so you can avoid accidentally adding an include so that it will be included "from everywhere". Think hard when you add a new include: do I really need to include this here? What other files will be drawn in when I do this?

    Two conventions (apart from those already mentioned) which can help out:

    • One class == one source file + one header file, consistently named. Class A goes in A.cpp and A.h. Code templates and snippets are good here to reduce the amount of typing needed to declare each class in a separate file.
    • Use the Impl-pattern to avoid exposing internal members in a header file. The impl pattern means putting all internal members in a struct defined in the .cpp file, and just have a private pointer with a forward declaration in the class. This means that the header file will only need to include those headerfiles needed for its public interface, and any definitions needed for its internal members will be kept out of the headerfile.
    0 讨论(0)
  • 2021-01-01 17:38

    In A.cpp, always include A.h first, to ensure that A.h has no additional dependencies. Include all local (same module) files before all project files before all system files, again to ensure that nothing depends on pre-included system files. Use forward declarations as much as possible. Use #indef/#define/#endif pattern If a header is included in A.h, you don't need to include it in A.cpp. Any other headers A.cpp needs must be explicitly included, even if they happen to be provided by other .h files.

    0 讨论(0)
提交回复
热议问题