Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circular Dependency in C++

The facts:

  • I have two predominant classes: Manager and Specialist.
  • There are several different types of Specialists.
  • Specialists often require the help of other Specialists in order to get their job done.
  • The Manager knows all of the Specialists, and initially each Specialist knows only their Manager. (This is the problem.)
  • At runtime, the Manager creates and stores a list of Specialists. Then the Manager iterates through the list and asks each Specialist to initialize. During their initialization, each Specialist asks the Manager to supply them with other Specialists that fulfill some description. Once this is complete, the Manager then goes into a loop during which the Specialists are asked sequentially to perform their specialized task.

To me it seems that this is a decent pattern, but since a Manager has a list of Specialists and a Specialist has a Manager I'm getting circular dependency problems.

Is this a case where I should somehow forward declare the existence of one class from another? (If so, how?) Or should I use some design pattern to fix this problem? (If so what?) Also... I though the pattern itself was pretty o.k. so I wouldn't mind someone helping me understand why this is a bad thing.

like image 711
JnBrymn Avatar asked Oct 25 '10 21:10

JnBrymn


People also ask

What is meant by circular dependency?

In software engineering, a circular dependency is a relation between two or more modules which either directly or indirectly depend on each other to function properly. Such modules are also known as mutually recursive.

How do you fix a circular dependency problem?

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 cyclic dependency in C++?

Circular Dependencies in C++Its goal is to draw the “include” dependencies between classes in a C++ project. In particular, it allows to detect circular dependencies very easily or to check the architecture of a project.

How can cyclic dependencies be prevented?

To reduce or eliminate circular dependencies, architects must implement loose component coupling and isolate failures. One approach is to use abstraction to break the dependency chain. To do this, you introduce an abstracted service interface that delivers underlying functionality without direct component coupling.


1 Answers

In both cases, forward declare the other class:

Manager.h

class Specialist;

class Manager
{
    std::list<Specialist*> m_specialists;
};

Specialist.h

class Manager;

class Specialist
{
    Manager* m_myManager;
};

The only time you need to bring in the header file for a class is when you need to use a member function or variable within that class, or need to use the class as a value type etc. When you only need a pointer or reference to a class, a forward declaration will suffice.

Note that forward declarations aren't just for solving circular dependencies. You should use forward declarations wherever possible. They are always preferable to including an extra header file if it is at all viable.

like image 114
Peter Alexander Avatar answered Sep 20 '22 08:09

Peter Alexander