== Why is this an issue?

Protected member variables are similar to global variables; any derived class can modify them. When protected member variables are used, invariants cannot be enforced. Also, protected member variables are hard to maintain since they can be manipulated through multiple classes in different files.


If a class is just a data store without logic, it can safely contain only ``++public++`` member variables and no member functions. Otherwise, data members are tightly coupled to the class logic, and encapsulation must be used. In this case, having only private member variables enforces invariants for data and ensures that logic is defined only in the member functions of the class. Structuring it this way makes it easier to guarantee integrity and easier for maintainers to understand the code.


Using ``++protected++`` member variables breaks the encapsulation. The risk is that data integrity logic spreads through the class and all its derived classes, becoming a source of complexity that will be error-prone for maintainers and extenders.


That is why ``++protected++`` member variables should be changed to ``++private++`` and manipulated exclusively through ``++public++`` or ``++protected++`` member functions of the base class.


This rule raises an issue when a ``++class++`` or ``++struct++`` contains ``++protected++`` member variables.


=== Noncompliant code example

[source,cpp,diff-id=1,diff-type=noncompliant]
----
class Stat {
public:
  long int getCount() {
    return count;
  }
protected:
  long int count = 0; // Noncompliant; expose a protected member variable.
                      // By just looking at "Stat" class, it's not possible to be sure that "count"
                      // is modified properly, we also need to check all derived classes
};

class EventStat : public Stat {
public:
  void onEvent() {
    if (count < LONG_MAX) {
      count++;
    }
  }
};
----


=== Compliant solution

[source,cpp,diff-id=1,diff-type=compliant]
----
class Stat {
public:
  long int getCount() {
    return count;
  }
protected:
  void increment() { // Compliant; expose a protected member function
    if (count < LONG_MAX) {
      count++;
    }
  }
private:
  long int count = 0; // member variable is private
};

class EventStat : public Stat {
public:
  void onEvent() {
    increment();
  }
};
----


=== Exceptions

Const member variables and reference member variables are ignored since they don't break invariants.


== Resources

* MISRA {cpp}:2008, 11-0-1 - Member data in non-POD class types shall be private.
* {cpp} Core Guidelines - https://github.com/isocpp/CppCoreGuidelines/blob/e49158a/CppCoreGuidelines.md#c133-avoid-protected-data[C.133: Avoid `protected` data]


ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

Make this member variable "private".


=== Highlighting

variable name


'''
== Comments And Links
(visible only on this page)

=== is duplicated by: S1018

=== on 23 Jun 2016, 11:58:37 Ann Campbell wrote:
Objective-C, [~alban.auzeill]?

endif::env-github,rspecator-view[]
