It's been a while since I have learned C++ from school. The last time I heard about circular dependency in C++ was from my sophomore year in college. Yesterday, I was having trouble making circular dependency to get working. I decided to post about how I solved the problems I had considering that circular dependency isn't a situation you encounter very often. I usually get rusty on things I don't do often. Hopefully, many people are like me and some may benefit from this post sometime later.


While at work designing an application, I encountered a situation where two classes had attributes of their own referring to another class in the following manner.
사용자 삽입 이미지
I recognized that this resulted in a circular dependency and included a forward declaration in the header file of each class for the class that it was referring to. So the header file for each class resulted in the following.
 
// A.h
class B;   // forward declaration for class B
class A
{
    private:
       B* pB
    public:
       ...
};

// B.h
class A;    // forward declaration for class A
class B
{
    private:
       A a;
    public:
       ...
};
However, I got a compile error indicating that class A and B were not defined. It was weird at first because I thought I got my circular dependency problem solved. I had no idea how to get around the compile error. My solution to this was to create another class to use it as a mediator for the establishing an associative relationship between class A and B. My new design was like the following.
사용자 삽입 이미지
I was stupid enough to think that this new design will avoid the circular dependency relationship. But after another build of my application, I figured that this also results in a circular dependency. If you look carefully at the #include statements in each header file for class A, B, and C,
    - A.h includes C.h
    - C.h includes B.h
    - B.h includes A.h
, but then B must compile A.cpp and A cannot be compiled because C and B has not been compiled. Therefore, class A is not defined and the circular dependency prevents the code to be compiled in spite of the forward declarations.

At this point, I realized that class A does not require C.cpp to be compiled. This is because that  class A refers to class C with a pointer. As you all know, pointers are usually a 4 byte (32 bit) integer and as long as the type of the pointer is specified, the code compiles. From what I have just realized, I decided to change my design like the following.
사용자 삽입 이미지
I could have gotten rid of class C but I kept it for another good reason (design issue in my application). As I changed all my inter class relationship into association, the code compiled as I expected and also worked fine.


The point I would like to make here is that it is important that you know that circular dependency only works only when classes are associated with each other based on pointers.

 Was this so obvious?
Posted by Dansoonie