Header files inclusion / Forward declaration

后端 未结 5 805
北海茫月
北海茫月 2020-12-24 03:39

In my C++ project when do I have to use inclusion (#include \"myclass.h\") of header files? And when do I have to use forward declaration of the class (cl

相关标签:
5条回答
  • 2020-12-24 04:02

    As a rule try the forward declaration first. This will reduce compile times etc. If that doesn't compile go for the #include. You have to go for the #include if you need to do any of the following:

    1. Access a member or function of the class.
    2. Use pointer arithmetic.
    3. Use sizeof.
    4. Any RTTI information.
    5. new/delete, copy etc.
    6. Use it by value.
    7. Inherit from it.
    8. Have it as a member.
    9. Instance in a function.

    (6,7,8,9 from @Mooing Duck)

    They're are probably more but I haven't got my language law hat on today.

    0 讨论(0)
  • 2020-12-24 04:08

    As a beginner, you should always #include header files when you need to use the types or functions they contain - do not try to "optimise" your build by forward declaring things - this is hardly ever necessary, even on large projects, provided the project is well architected.

    The only time you absolutely need a forward declaration is in situations like this:

    struct A {
       void f( B b );
    };
    
    struct B {
       void f( A a );
    };
    

    where each struct (or class) refers to the type of the other. In this case, you need a forward declaration of B to resolve the issue:

    struct B;   // forward declaration
    
    struct A {
       void f( B b );
    };
    
    struct B {
       void f( A a );
    };
    
    0 讨论(0)
  • 2020-12-24 04:13

    There are several problems to forward declaration:

    • It is like storing your class name in multiple places -- if you change it in one place, you now have to change it everywhere else. Refactoring becomes a challenge since the code will still compile fine with the changed class name, but linking will fail since the forward declarations refer to an undefined class. If you include the header file and do not use forward declarations, you will catch these problems during compilation.
    • Forward declarations are difficult for others to maintain. For instance, if a header file contains:

      include "MyProject/MyWidgets/MyFooWidgets/FooUtil/Foo.h"
      

      rather than the forward declaration

       class Foo ;  
      

      it is easy for others to find where the class Foo is declared. With forward declaration, it is not that obvious; some IDEs like Eclipse may open the forward declaration when the user tries to open the declaration of a variable.

    • Linking can fail with undefined symbol errors when you include a header file in your code that contains a forward declaration but the actual code definition is located in some other library that you did not link with. It's more convenient to catch this problem at compile time with errors like "Could not find file MyProject/MyWidgets/MyFooWidgets/FooUtil/Foo.h" since then you will know where to look for the corresponding Foo.cpp and identify the library that contains it.

    If you think your build is taking too long, then try doing a compile only with no link. If your code takes 10 seconds to compile and 10 minutes to link, the problem has nothing to do with a few extra includes. Similarly, if your header file contains so much stuff in it that it is actually causing a performance problem then it is probably time for you to refactor the content of that file into multiple smaller header files.

    So when is it OK to forward declare? If you do it in the same header file as the real declaration.

    Example:

    class Foo ;
    
    typedef Foo* FooPtr ;
    typedef Foo& FooRef ;
    
    class Foo
    {
       public:
          Foo( ) ;
          ~Foo( ) ;
    }
    

    OR

    class TreeNode ;
    
    class Tree
    {
    private:
       TreeNode m_root ;
    }
    
    class TreeNode
    {
       void* m_data ;
    } ;
    
    0 讨论(0)
  • 2020-12-24 04:17

    If you only need a pointer to the class and you don't need any knowledge about the class rather than its name, you can use the forward declaration.

    0 讨论(0)
  • 2020-12-24 04:25

    You should strive towards minimizing your #includes both in order to reduce compilation times but also to help with modularity and testability. As @ypnos says, class forwards are excellent when you only need pointers.

    For some practical tips on how to reduce header dependencies, see e.g. this article.

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