Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding Circular Dependencies of header files [duplicate]

People also ask

How do you fix cyclic dependencies?

There are a couple of options to get rid of circular dependencies. For a longer chain, A -> B -> C -> D -> A , if one of the references is removed (for instance, the D -> A reference), the cyclic reference pattern is broken, as well. For simpler patterns, such as A -> B -> A , refactoring may be necessary.

What is a circular dependency in C++?

Suppose that you have two classes A and B. If A uses B and conversely then there is a circular dependency. However, the circular dependency maybe subtler. For instance, it may be A that uses B that uses C that uses A. In C++, if a file “A.h” includes “B.h” then “B.h” cannot include “A.h”.

When to include header files in c++?

A header file should be included only when a forward declaration would not do the job. The header file should be so designed that the order of header file inclusion is not important. The header file inclusion mechanism should be tolerant to duplicate header file inclusions.

Do header files need includes?

Such project header files should contain #include statements for the system headers; if the body includes them first, the compiler does not check this.


If you have circular dependency then you doing something wrong.

As for example:

foo.h
-----
class foo {
public:
   bar b;
};

bar.h
-----
class bar {
public:
   foo f;
};

Is illegal you probably want:

foo.h
-----
class bar; // forward declaration
class foo {
   ...
   bar *b;
   ...
};

bar.h
-----
class foo; // forward declaration
class bar {
   ...
   foo *f;
   ...
};

And this is ok.

General rules:

  1. Make sure each header can be included on its own.
  2. If you can use forward declarations use them!

  • Use forward declarations where possible.
  • Move any header includes out of a header file and into the corresponding cpp file if they are only needed by the cpp file. Easiest way to enforce this is to make the #include "myclass.h" the first include in myclass.cpp.
  • Introducing interfaces at the point of interaction between separate classes can help reduce dependencies.

Some best practices I follow to avoid circular dependencies are,

  1. Stick to OOAD principles. Don't include a header file, unless the class included is in composition relationship with the current class. Use forward declaration instead.
  2. Design abstract classes to act as interfaces for two classes. Make the interaction of the classes through that interface.

A general approach is to factor out the commonalities into a third header file which is then referenced by the two original header files.

See also Circular Dependency Best Practice