lo tolmencre lo tolmencre - 7 days ago 7
C++ Question

Mutual Import C++

I know this is a reoccurring question, but so far I have basically only seen the answer “if you have mutual imports you are doing something wrong”.

That is why I have more of a general understanding question than one tied to some specific code.

Okay, so as an example. Say I have a data structure for a dynamic automaton. The states of the automaton are structs with an attribute “transitions”. “transitions” is a dynamic linked list. The list elements are structs that have as an attribute a State object...

So:

// state.h
#include "transitionList.h"

State{
TransitionList transitions; // all transitions going out from this state
}

// tranistion.h
#include "state.h"

Transition{
Transition* next_transition; // the next transition in the TransitionList
State* successor; // a pointer to the next state in the automaton
}


// transitionList.h
#include "tranisiton.h"

TransitionList{
// *code* class for a linked list of transitions
}


So we have state.h -> tranistion.h -> transitionList.h -> state.h -> …

This is obviously circular... but where is the conceptual mistake? I don't see how this is a bad layout from a formal point of view.

Please enlighten me :)

Answer

Conceptually it's fine. It's just physically not going to work because C++ doesn't have a physical module system. The #include directive just inserts a copy of the included file, so circular includes will produce a source stream of infinite length.

You need to present the compiler with the classes in a certain order that it can compile, the combination being known as a "translation unit".

Where you have a class that holds a pointer to another class that has not yet been fully declared, you have to "forward declare" it:

class State;

That trick allows one of the class headers to not need to include the full definition of something that it holds a pointer to, and breaks the loop.