My question is if there is any specifiq workflow when you have two classes referencin each other. In the example, you can see that it is requiered apparently to do an empty class declaration on "Context", since "State" refences it right after in 'void set_context(Context *context)"'. Then when you define the class "Context", "State" is refence too as private memenber.
So it isn't ideal to wright code like that because you are forced to follow a specific sequence, and any refactoring can potentially break the code.
Does c++ has any mechanisms for this?
#include <iostream>
#include <typeinfo>
class Context; // first, declaration to be able to use in State
class State {
protected:
Context *context_;
public:
virtual ~State() {
}
void set_context(Context *context) {
this->context_ = context;
}
virtualvoid Handle1() = 0;
virtualvoid Handle2() = 0;
};
class Context { // Actual definition
private:
State *state_;
public:
Context(State *state) : state_(nullptr) {
this->TransitionTo(state);
}
// ... more code
}
EDIT: Got the includes mixed up. Now they're correct.
As long as you use forward declarations whenever you can and only include headers in the files that need the full class definition then these sort of circular dependencies are unlikely to cause any problems.
Note that in your real code you might have to include State.h from Context.cpp and Context.h from State.cpp. That's not going to cause any problems.
In some situations you might also need to include one of the headers from the other header but that is not an issue if only one of the headers does it. But if both headers tried to include each other that would not work.
The above is how I have solved problems in the past and it has worked pretty well.
But I'm not sure it's necessarily the "best" way to do it. It's quite nice to avoid circular dependencies if you can so if you could write your code so that the dependency only went in one direction (e.g. Context knows about State but State knows nothing about the Context) that might be a better approach.
C++20 added something called "modules" which is intended to be a modern replacement for .h/.cpp files (kind of). Compiler and tool support for this feature is still a bit lacking so I haven't tested it yet but my understanding is that you're not going to be able to forward declare types from other modules so I'm thinking that maybe I will have to force myself to write my code to avoid these kind of circular dependences all together (which might be a good thing, I don't know yet) ... or maybe I'll need to put multiple classes inside the same module?
cool,
Sure, I use headers and source files in all my projects. But was getting a circular dependency in this example. The solution is as you posted. Simply declare class context at the beggining of state.h. Thanks.
About circular dependencies sometime they are actually part of the pattern itself.
State, Visitor, and other pattern requiere a ciruclar dependency because referencing each other is part of the design. But I agree as a general rule it is better to avoid them.