Minimize exposure of members
Reason
Encapsulation. Information hiding. Minimize the chance of unintended access. This simplifies maintenance.
Example
template<typename T, typename U>
struct pair {
T a;
U b;
// ...
};
Whatever we do in the //-part, an arbitrary user of a pair can arbitrarily and independently change its a and b. In a large code base, we cannot easily find which code does what to the members of pair. This might be exactly what we want, but if we want to enforce a relation among members, we need to make them private and enforce that relation (invariant) through constructors and member functions. For example:
class Distance {
public:
// ...
double meters() const { return magnitude*unit; }
void set_unit(double u)
{
// ... check that u is a factor of 10 ...
// ... change magnitude appropriately ...
unit = u;
}
// ...
private:
double magnitude;
double unit; // 1 is meters, 1000 is kilometers, 0.001 is millimeters, etc.
};
Note
If the set of direct users of a set of variables cannot be easily determined, the type or usage of that set cannot be (easily) changed/improved. For public and protected data, that's usually the case.
Example
A class can provide two interfaces to its users. One for derived classes (protected) and one for general users (public). For example, a derived class might be allowed to skip a run-time check because it has already guaranteed correctness:
class Foo {
public:
int bar(int x) { check(x); return do_bar(x); }
// ...
protected:
int do_bar(int x); // do some operation on the data
// ...
private:
// ... data ...
};
class Dir : public Foo {
//...
int mem(int x, int y)
{
/* ... do something ... */
return do_bar(x + y); // OK: derived class can bypass check
}
};
void user(Foo& x)
{
int r1 = x.bar(1); // OK, will check
int r2 = x.do_bar(2); // error: would bypass check
// ...
}
Note
Note
Prefer the order public members before protected members before private members; see NL.16.
Enforcement
- Flag protected data.
- Flag mixtures of
publicandprivatedata
C.concrete: Concrete types
Concrete type rule summary: