Закрытое (private) наследование 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Закрытое (private) наследование



 

Закрытые члены базового класса недоступны напрямую с использованием дополнительных методов класса-наследника (при любом способе наследования). Работа внутри класса-наследника с такими получаемыми закрытыми членами базового класса возможна только с использованием открытых и защищенных методов базового класса.

 

Закрытые и защищенные получаемые методы недоступны для манипули-рования с объектом вне класса. Они могут использоваться как подпрограммы другими методами класса.

 

При закрытом наследовании открытые и защищенные члены базового класса (любые) доступны только внутри производного класса и недоступны извне (через объекты производного класса), как и его собственные закрытые члены.

Таким образом, приведенная таблица показывает вид доступа для членов в типе наследнике для типа наследника следующего уровня. Но, для текущего ти-па-наследника доступность зависит от вида доступа в базовом типе.

 

Пример:

 

class X1{

 

int ix1; public:

int f1(){... }

 

...

 

};

 

class Y1: protected X1 {

 

...

 

};

 

class Z1: public Y1 {

 

...

 

};

 

class X2{ protected:

 

int ix2; public:

 

int f2(){... }

 

...

 

};

 

class Y2: X2 {...};

 

class Z2: public Y2 {...};

 

В классе Y1 переменная ix1 недоступна непосредственно, так как она в базовом классе X1 находится в закрытой области. Однако она может быть ис-пользована в функции f1(). В то же время функция f1() не может использо-ваться в качестве внешнего метода по отношению к объекту, созданному на ос-нове класса Y1, так как она находится в защищенной области класса Y1. Это же остается справедливым и для класса Z1. В классе Y2 переменная ix2, в отличие от переменной ix1 в классе Y2, доступна непосредственно. В классе Z2 пере-менная ix2 становится недоступной для непосредственного использования, так же, как и переменная ix1 в классе Z1. Другие отличия классов Z1 и Z2: в отличие от функции f1() в классе Z1, функция f2() в классе Z2 доступна в классе Z2 качестве внутренней подпрограммы, только для функций, унаследованных из класса Y2, так как в классе Y2 она находится в закрытой области.

 

Закрытое наследование целесообразно в том случае, когда меняется сущ-ность нового объекта.

 

Пример: Базовый класс описывает фигуры на плоскости и имеет методывычисления площади фигур, а класс-наследник описывает объемные тела, на-пример, призмы с основанием – плоской фигурой, описываемой базовым классом. В этом случае объем тела, описываемого классом-наследником, вычисляется умножением площади основания на высоту. При этом не имеет значения, каким образом получена площадь основания. Кроме того, методы работы с объемными объектами отличны от методов работы с плоскими объектами. Поэтому в данном случае не имеет смысла наследование методов базового класса для работы с объектами, описываемыми классом-наследником:

 

#include <iostream> using namespace std;

 

class twom { double x,y;

 

public:

 

twom(double x1=1, double y1=1): x(x1), y(y1) {} double sq(){

 

return x*y;

 

}

 

};

 

class thm: private twom { double z;

public:

 

thm(double x1 = 1, double y1 = 1, double z1 = 1):twom(x1,y1), z(z1){}

 

double vol(){ return sq()*z;}

 

};

 

int main(){

 

thm t1(1,2,3); double d1;

 

d1 = t1.vol();

 

cout << "vol= " << d1 << '\n'; return 0;

}

 

Таким образом, закрытое наследование несколько напоминает композицию объектов, когда подобъект находится в закрытой области. Все же необходимо помнить, что наследование – это совсем другая концепция ассоциирования классов, по многим своим свойствам отличная от агрегации, даже в ее строгом варианте (композиции).

 

Перекрытие имен

 

В производном классе могут использоваться имена членов класса, пере-крывающие видимость таких же имен в базовом классе (overriding). При пере-крытии имен при работе с объектом через указатель будет исполняться тот метод, который содержится в классе, используемом в объявлении указателя, независимо от типа объекта, на который указывает указатель.

 

Пример:

 

#include <iostream> using namespace std;

 

class A { public:

 

void f(int x){

 

cout << "A::f" << '\n';

 

}

 

};

 

class C: public A{ public:

 

void f(int x){

 

cout << "C::f" << '\n';

 

}

 

};    
intmain(){    
A a1;    
A* pa;    
C c1;    
C* pc;    
pc = &c1; // C::f  
pc -> f(1);  
pa = pc; // A::f – несмотря на то, что pa указывает  
pa -> f(1);  
  // на объект c1 типа класс C.  
     

pc = (C*)& a1; // Небезопасное преобразование указателя

 

// на объект базового класса к указателю

 

// на объект производного класса (данное

 

// преобразование должно объявляться

// явно, иначе – ошибка).

 

pc -> f(1); // C::f – несмотря на то, что pa указывает

 

// на объект а1 типа класс А. В общем

// случае такой вызов некорректен.

 

return 0;

 

}

 

Члены базового класса с именами, совпадающими с именами членов про-изводного класса, доступны в производном классе. Для доступа к ним необходимо указывать квалификатор (имя базового класса) с использованием операции ‘::’, так как данные члены находятся в доступной области видимости, которая не совпадает с текущей областью видимости. Также метод базового класса доступен через указатель класса-наследника при условии использования квалификатора.

 

Пример:

 

#include <iostream> using namespace std;

 

class A { public:

 

void f(int x){cout<<"A::f"<<'\n';}

 

};

 

class C: public A{ public:

 

void f(int x){

 

cout << "C::f" << '\n';

}

 

void g(){f(1); A::f(1);

 

}

 

};

 

int main(){C c1; C* pc; pc=&c1;

 

pc->A::f(1); // вызов метода базового класса с

// использованием указателя

 

// класса–наследника.

 

pc->f(1); pc->g(); return 0;

 

}

 

 

Таким образом, при перекрытии методы базового класса не «затираются» в классе-наследнике. Они доступны через квалификатор.

 



Поделиться:


Последнее изменение этой страницы: 2017-02-05; просмотров: 160; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.59.34.87 (0.013 с.)