Search code examples
c++header-filesforward-declaration

c++ Getting forward declaration correct with complex dependencies


Problem

I am getting the following compilation error:

error: member access into incomplete type 'IRB'

This happens at the first line that class IRB is used, at HG.h.

Questions

  • What am I missing here? Is it the typedef that is causing the issues?

  • On each header file, as you can see below I forward declared the class that I am going to use.

  • More importantly what is the process that I should follow to get this correct?

Header files

T.h

typedef IRBBase__<true, true> IRB_BASE;  // typedef a template instantiation

IRB.h

#include "T.h"
#include "FH.h"
class FH; // FWD DCLR
class IRB : IRB_BASE {..};

FH.h

#include "T.h"
#include "IRB.h"
#include "HG.h"
class IRB;  // FWD DCLR
class HG;   // FWD DCLR
class FH {..};

HG.h

#include "T.h"
#include "FH.h"
#include "IRB.h"
#include "CU.h"
class FH;   // FWD DCLR
class IRB;  // FWD DCLR
class CU;   // FWD DCLR
class HG {..};

CU.h

#include "T.h"
#include "IRB.h"
#include "FH.h"
class IRB;
class FH;
class CU {..};

Edit: Got it working

After user0042 suggestion, I got it working by moving headers from all files except HG.h into their respective .cc files. In HG.h I kept the forward declarations, and the header files.


Solution

  • This answer is based on the comments I've received.

    The function declarations in the header files might be using the class we wan't to include, but this might cause cycling dependencies.

    So the solution is:

    • to move the #include's of the classes we mention in the header file to the source file
    • in the header file do a forward declaration of the class

    This can be done for any classes that are not used in the header. If we are using the header, like in the following example HG.h, we should keep the #include's in the header file.

    Solution of the example in question

    T.h

    typedef IRBBase__<true, true> IRB_BASE;  // typedef a template instantiation
    

    IRB.h

    class FH; // FWD DCLR
    class IRB : IRB_BASE {..};
    

    FH.h

    class IRB;  // FWD DCLR
    class HG;   // FWD DCLR
    class FH {..};
    

    HG.h

    #include "T.h"
    #include "FH.h"
    #include "IRB.h"
    #include "CU.h"
    class FH;   // FWD DCLR
    class IRB;  // FWD DCLR
    class CU;   // FWD DCLR
    class HG {..
       // some of the classes are used here, because some functions
       // were too small and kept them in the header file (defined the function)
       // if the same had happened with another of the headers, causing a
       // cyclic include dependency, then I should have converted
       // some of the function definitions into declarations, and move the
       // implementation of the file in the source file (.cc)
    };
    

    CU.h

    class IRB;
    class FH;
    class CU {..};