Search code examples
c++variablescompiler-errorsprotectedclang-tidy

What are the risks of variables with protected visibility


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:

  1. What are the risks on giving a variable with protected visibility?
  2. Does anyone have any suggestions on how to solve this error in a clean way? (I've tought about creating a protected getter method, but if I want to act upon the correct context i will have to return a reference or pointer, which has the same effect as this, but just requires extra code).

Solution

    1. 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.

    2. 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.