Программирование на C и C++

Онлайн справочник программиста на C и C++

Спецификатор доступа при наследовании базового класса

От того, с каким спецификатором доступа объявляется наследование базового класса, зависит статус доступа к членам производного класса. Общая форма наследования классов имеет следую­щий вид:

class имя_класса: доступ имя_класса {
....
};

Здесь доступ определяет, каким способом наследуется базовый класс. Спецификатор доступ может принимать три значения — private, public и protected. В случае, если спецификатор дос­туп опущен, то по умолчанию подразумевается на его месте спецификатор public. Если специ­фикатор доступ принимает значение public, то все публичные и защищенные члены базового класса становятся соответственно публичными и защищенными членами производного класса. Если спецификатор доступ имеет значение private, то все публичные и защищенные члены базо­вого класса становятся частными членами производного класса. Если спецификатор доступ при­нимает значение protected, то все публичные и защищенные члены базового класса становятся защищенными членами производного класса. Для того чтобы усвоить все эти преобразования, рассмотрим пример:

#include <iostream.h>
class X {
protected:
int i;
int j;
public:
void get_ij () {
cout << "Enter two numbers: ";
cin >> i >> j;
}
void put_ij() { cout << i << " " << j << "\n"; }
};
// в классе Y, i и j класса X становятся защищенными членами
class Y: public X {
int k;
public:
int get_k() { return k; }
void make_k() { k = i*j; }
};
/* класс Z имеет доступ к i и j класса X, но не к k класса Y, поскольку он является частным */
class Z: public Y {
public:
void f();
};
// i и j доступны отсюда
void z::f()
{
i = 2; // нормально
j = 3; // нормально
}
int main()
{
Y var;
Z var2;
var.get_ij();
var.put_ij();
var.make_k();
cout << var.get_k();
cout << "\n";
var2.f();
var2.put_ij();
return 0;
}

Поскольку класс Y наследует класс X со спецификатором доступа public, то защищенные элемен­ты класса X становятся защищенными элементами класса Y. Это означает, что они могут далее наследоваться классом Z, и эта программа будет откомпилирована и выполнена корректно. Од­нако, если изменить статус X при объявлении Y на private, то, как доказано в следующей про­грамме, класс Z не имеет права доступа к i и j и к функциям get_ij() и put_ij(), поскольку они стали частными членами Y:

#include <iostream.h>
class X {
protected:
int i;
int j;
public:
void get_ij(){
cout << "Enter two numbers: ";
cin >> i >> j;
}
void put_ij() { cout << i << " " << j << "\n"; }
};
// теперь i и j преобразованы к частным членам Y
class Y: private X {
int k;
public:
int get_k() { return k; }
void make_k() { k = i*j; }
};
/* поскольку i и j частные для Y, они не могут наследоваться в Z */
class Z: public Y {
public:
void f();
};
// теперь данная функция не работает
void Z::f()
{
// i = 2; i и j больше не доступны
// j = 3;
}
int main()
{
Y var;
Z var2;
// var.get_ij(); больше не доступна
// var.put_i j(); больше не доступна
var .make_k();
cout << var.get_k();
cout << " \n";
var2.f();
// var2.put_ij(); больше не доступна
return 0;
}

Когда при объявлении класса Y перед базовым классом X имеется спецификатор доступа private, члены i, j, get_ij() и put_ij() становятся частными членами Y и поэтому не могут наследоваться классом Z, так что класс Z не имеет больше к ним доступа.