В С++ члены класса классифицируются в соответствии с правами доступа на следующие три категории: публичные (public), частные (private) и защищенные (protected). Любая функция программы имеет доступ к публичным членам. Доступ к частному члену имеют только функции-члены класса или функции-друзья класса. Защищенные члены аналогичны частным членам. Разница между ними появляется только при наследовании классов.
Когда один класс наследует другой, все публичные члены базового класса становятся публичными членами производного класса. В противоположность этому частные члены базового класса не доступны внутри производного класса. Например, рассмотрим следующий фрагмент:
class X {
int i;
int j;
public:
void get_ij();
void put_ij();
};
class Y: public X {
int k;
public:
int get_k();
void make_k();
};
Класс Y наследует и имеет доступ к публичным функциям get_ij() и put_ij() класса X, но не имеет доступа к i и j, поскольку они являются частными членами X. Во всех случаях частные члены остаются частными, т. е. доступными только в том классе, в котором они объявлены. Таким образом, частные члены не могут участвовать в наследовании.
В связи с тем, что частные члены не могут быть наследованы, возникает интересный вопрос: что если необходимо оставить член частным и вместе с тем позволить использовать его производным классам? Для таких целей имеется другое ключевое слово — protected (защищенный). Защищенный член подобен частному, за исключением механизма наследования. При наследовании защищенного члена производный класс также имеет к нему доступ. Таким образом, указав спецификатор доступа protected, можно позволить использовать член внутри иерархии классов и запретить доступ к нему извне этой иерархии. Например:
class X {
protected:
int i;
int j;
public:
void get_ij();
void put_ij();
};
class Y: public X {
int k;
public:
int get_k();
void make_k();
};
Здесь класс Y имеет доступ к i и j, и в то же время они остаются недоступными для остальной части программы. Когда элемент объявляется защищенным, доступ к нему ограничивается, но вместе с тем можно наследовать права доступа. В отличие от этого в случае частных членов доступ не наследуется.
Другой важной особенностью ключевых слов private, protected и public служит то, что они могут появляться в объявлении в любом порядке и в любом количестве. Например, следующий код является вполне законным:
class my_class {
protected:
int i;
int j;
public:
void f1();
void f2();
protected:
int a;
public:
int b;
};
Однако считается хорошим стилем, чтобы каждый из спецификаторов доступа встречался в объявлении класса не более одного раза.