Breaking cyclic references more elegant in C++

202 Views Asked by At

I have gotten many cyclic dependencies recently when my header files includes each other. See also here: What are forward declarations in C++?

I actually do not get totally why its a cycle. When the compiler looks inside the header-file of the include, why does it not recognize the class declaration?

Is there an more elegant/other way to break these cycles instead of a forward declaration of the other class? I do not like that there is a other class declaration in front of my current class. E.g.

#include "Wheel.h"  // Include Wheel's definition so it can be used in Car.
#include <vector>

class Wheel;

class Car
{
    std::vector<Wheel> wheels;
};
2

There are 2 best solutions below

0
calynr On BEST ANSWER

I hope I got your stuck point.

To explain this, it is better to examine from the view of compiler.

Compiler does for Car.h:

  • Replaces #include "Wheel.h" with its content.
  • Replaces #include <vector> with its content.

At this step, translation unit for Car.h seems like this.

class Car;

class Wheel
{
    Car* car;
};

// Vector implementation of the stl goes here

class Car
{
    std::vector<Wheel> wheels;
};

At this point, at Car* car; line, class Car declaration (declaration is enough for pointer types) is needed to define class Wheel that's why you need forward declaration because you should tell to compiler that there is a class Car and it will be defined soon.

If you comment out class Car at line 1 compiler could not know whether there will be a class Car or not.

As far as I know there are extra restrictions related with one definition rule, maybe someone else might explain that.

It is not possible to have 'more elegant' way for now.

2
Felipe Matos Mendes On

Will can use in each file the directives #ifndef ... #define #endif

So your code will became something like

#ifndef CAR_H
#define CAR_H
#include "Wheel.h"  // Include Wheel's definition so it can be used in Car.
#include <vector>

class Car
{
    std::vector<Wheel> wheels;
};

#endif

Do it in all your header files, so each file will be loaded at most once and the cycles will not happen anymore