What should go into an .h file?

后端 未结 12 813
伪装坚强ぢ
伪装坚强ぢ 2020-11-22 15:26

When dividing your code up into multiple files just what exactly should go into an .h file and what should go into a .cpp file?

相关标签:
12条回答
  • 2020-11-22 15:49

    in addition to all other answers, i will tell you what you DON'T place in a header file:
    using declaration (the most common being using namespace std;) should not appear in a header file because they pollute the namespace of the source file in which it is included.

    0 讨论(0)
  • 2020-11-22 15:49

    Your class and function declarations plus the documentation, and the definitions for inline functions/methods (although some prefer to put them in separate .inl files).

    0 讨论(0)
  • 2020-11-22 15:49

    the header file (.h) should be for declarations of classes, structs and its methods, prototypes, etc. The implementation of those objects are made in cpp.

    in .h

        class Foo {
        int j;
    
        Foo();
        Foo(int)
        void DoSomething();
    }
    
    0 讨论(0)
  • 2020-11-22 15:51

    In general, you put declarations in the header file and definitions in the implementation (.cpp) file. The exception to this is templates, where the definition must also go in the header.

    This question and ones similar to it has been asked frequently on SO - see Why have header files and .cpp files in C++? and C++ Header Files, Code Separation for example.

    0 讨论(0)
  • 2020-11-22 15:58
    • Header files - shouldn't change during development too often -> you should think, and write them at once (in ideal case)
    • Source files - changes during implementation
    0 讨论(0)
  • 2020-11-22 15:59

    Fact is, in C++, this is somewhat more complicated that the C header/source organization.

    What does the compiler see?

    The compiler sees one big source (.cpp) file with its headers properly included. The source file is the compilation unit that will be compiled into an object file.

    So, why are headers necessary?

    Because one compilation unit could need information about an implementation in another compilation unit. So one can write for example the implementation of a function in one source, and write the declaration of this function in another source needing to use it.

    In this case, there are two copies of the same information. Which is evil...

    The solution is to share some details. While the implementation should remain in the Source, the declaration of shared symbols, like functions, or definition of structures, classes, enums, etc., could need to be shared.

    Headers are used to put those shared details.

    Move to the header the declarations of what need to be shared between multiple sources

    Nothing more?

    In C++, there are some other things that could be put in the header because, they need, too, be shared:

    • inline code
    • templates
    • constants (usually those you want to use inside switches...)

    Move to the header EVERYTHING what need to be shared, including shared implementations

    Does it then mean that there could be sources inside the headers?

    Yes. In fact, there are a lot of different things that could be inside a "header" (i.e. shared between sources).

    • Forward declarations
    • declarations/definition of functions/structs/classes/templates
    • implementation of inline and templated code

    It becomes complicated, and in some cases (circular dependencies between symbols), impossible to keep it in one header.

    Headers can be broken down into three parts

    This means that, in an extreme case, you could have:

    • a forward declaration header
    • a declaration/definition header
    • an implementation header
    • an implementation source

    Let's imagine we have a templated MyObject. We could have:

    // - - - - MyObject_forward.hpp - - - - 
    // This header is included by the code which need to know MyObject
    // does exist, but nothing more.
    template<typename T>
    class MyObject ;
    

    .

    // - - - - MyObject_declaration.hpp - - - - 
    // This header is included by the code which need to know how
    // MyObject is defined, but nothing more.
    #include <MyObject_forward.hpp>
    
    template<typename T>
    class MyObject
    {
       public :
          MyObject() ;
       // Etc.
    } ;
    
    void doSomething() ;
    

    .

    // - - - - MyObject_implementation.hpp - - - - 
    // This header is included by the code which need to see
    // the implementation of the methods/functions of MyObject,
    // but nothing more.
    #include <MyObject_declaration.hpp>
    
    template<typename T>
    MyObject<T>::MyObject()
    {
       doSomething() ;
    }
    
    // etc.
    

    .

    // - - - - MyObject_source.cpp - - - - 
    // This source will have implementation that does not need to
    // be shared, which, for templated code, usually means nothing...
    #include <MyObject_implementation.hpp>
    
    void doSomething()
    {
       // etc.
    } ;
    
    // etc.
    

    Wow!

    In the "real life", it is usually less complicated. Most code will have only a simple header/source organisation, with some inlined code in the source.

    But in other cases (templated objects knowing each others), I had to have for each object separate declaration and implementation headers, with an empty source including those headers just to help me see some compilation errors.

    Another reason to break down headers into separate headers could be to speed up the compilation, limiting the quantity of symbols parsed to the strict necessary, and avoiding unecessary recompilation of a source who cares only for the forward declaration when an inline method implementation changed.

    Conclusion

    You should make your code organization both as simple as possible, and as modular as possible. Put as much as possible in the source file. Only expose in headers what needs to be shared.

    But the day you'll have circular dependancies between templated objects, don't be surprised if your code organization becomes somewhat more "interesting" that the plain header/source organization...

    ^_^

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