с дружественностью базовый класс может
Однако по аналогии с дружественностью базовый класс может разрешить доступ к своим элементам личной части в производных классах. Это делается при помощи объявления защищенных
(protected) элементов.
Элемент с меткой
protected в базовом классе входит в личную часть базового класса. Кроме того, он доступен и в личной части производного класса. Если же базовый класс включается в производный как public, то защищенный элемент становится защищенным и в производном классе, то есть может использоваться в последующих производных классах.
Сказанное поясним примером:
class A
{
int a1; // Обычный личный элемент
protected:
int a2; // Защищенный личный элемент
public:
};
//----- Вариант 1: наследование без public ---------------
class B : A // a1,a2 в личной части B
{
void x();
};
void B::x()
{
a1 = 5; // Ошибка: a1 недоступен в B
a2 = 3; // a2 доступен в личной части B
}
//----- Вариант 2: наследование с public ------------------
class B : public A // a2 доступен и защищен в личной
{ // части B, неявно имеет место protected: int a2;
};
Применительно к базовому и производному классу можно сказать, что, преобразуя указатель на объект производного класса к указателю на объект базового класса, мы получаем доступ к
вложенному объекту базового класса. Но при такой трактовке преобразования типа указателя транслятору необходимо учитывать размещение объекта базового класса в производном, что он и делает. В результате значение указателя (адрес памяти) на объект базового класса может оказаться не равным исходному значению указателя на объект производного. Ввиду " особости" такого преобразования оно может быть выполнено в Си++ неявно (остальные преобразования типов указателей должны быть явными).
Побочный эффект такого преобразования состоит в том, что транслятор "забывает" об объекте производного класса и вместо переопределенных в нем функций вызывает функции базового:
class A
{
public: void f1();
};
class B : A
{
public: void f1(); // Переопределена в классe B
Содержание Назад Вперед