I'm trying to implement a state pattern as explained in this example. I've gotten to code similar as below.
class State {
public:
virtual void enter() {};
virtual void update() = 0;
virtual void exit() {};
virtual void setContext(Context* cxt) {
this->context = cxt;
}
protected:
Context* context;
};
class Context {
public:
void do_something();
void do_something_else();
void transitionTo(std::unique_ptr<State> next_state) {
if (state != nullptr) {
state->exit();
}
state = std::move(next_state);
state->setContext(this);
state->enter();
}
private:
std::unique_ptr<State> state;
};
class ConcreteStateA : public State {
public:
void update() override {
try {
context->do_something();
} catch {
context->transitionTo(std::unique_ptr<ConcreteStateB>());
}
}
};
class ConcreteStateB {
// ...
};
However, when i try to compile this with clang-tidy i get the following warning
error: member variable 'context' has protected visibility [cppcoreguidelines-non-private-member-variables-in-classes,-warnings-as-errors]
I have the following 2 questions:
You are not correct in saying
i will have to return a reference or pointer, which has the same effect as this, but just requires extra code
since exposing the pointer via making it protected allows the derived type to manipulate the pointer itself, not only the underlying data.
From documentation of the
misc-non-private-member-variables-in-classes check for which
cppcoreguidelines-non-private-member-variables-in-classes
is an
alias:
The data members should be declared as private and accessed through member functions instead of exposed to derived classes or class consumers.