Минимизируйте открытость членов
Причина
Инкапсуляция. Сокрытие информации. Минимизируйте вероятность непреднамеренного доступа. Это упрощает сопровождение.
Пример
template<typename T, typename U>
struct pair {
T a;
U b;
// ...
};
Что бы мы ни делали в части //, любой пользователь pair может произвольно и независимо изменять a и b. В большой кодовой базе нелегко найти, какой код что делает с членами pair. Возможно, это именно то, что нам нужно, но если мы хотим обеспечить связь между членами, нам нужно сделать их private и поддерживать эту связь (инвариант) через конструкторы и функции-члены. Например:
class Distance {
public:
// ...
double meters() const { return magnitude*unit; }
void set_unit(double u)
{
// ... проверяем, что u является степенью 10 ...
// ... изменяем magnitude соответственно ...
unit = u;
}
// ...
private:
double magnitude;
double unit; // 1 — метры, 1000 — километры, 0.001 — миллиметры и т.д.
};
Примечание
Если набор прямых пользователей набора переменных не может быть легко определён, тип или использование этого набора не может быть легко изменено/улучшено. Для public и protected данных это, как правило, так и есть.
Пример
Класс может предоставлять своим пользователям два интерфейса. Один для производных классов (protected) и один для общих пользователей (public). Например, производный класс может пропустить проверку во время выполнения, поскольку он уже гарантировал корректность:
class Foo {
public:
int bar(int x) { check(x); return do_bar(x); }
// ...
protected:
int do_bar(int x); // выполняет некую операцию над данными
// ...
private:
// ... данные ...
};
class Dir : public Foo {
//...
int mem(int x, int y)
{
/* ... делаем что-то ... */
return do_bar(x + y); // OK: производный класс может обойти проверку
}
};
void user(Foo& x)
{
int r1 = x.bar(1); // OK, проверка выполняется
int r2 = x.do_bar(2); // ошибка: обходит проверку
// ...
}
Примечание
protected данные — плохая идея.
Примечание
Предпочтительный порядок: public члены перед protected, protected перед private; см. NL.16.
Контроль
- Помечать
protectedданные. - Помечать смешение
publicиprivateданных
C.concrete: Конкретные типы
Краткое изложение правил для конкретных типов: