Вопрос 26: Закрытое наследование и его альтернатива - включение.

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

Общая форма наследования классов имеет следующий вид:

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

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

ДЛЯ СПРАВКИ:Спецификатор доступа может принимать три значения — private, public и protected. В случае, если спецификатор доступ опущен, то по умолчанию подразумевается на его месте спецификатор private. Если спецификатор доступ принимает значение public, то все публичные и защищенные члены базового класса становятся соответственно публичными и защищенными членами производного класса. Если спецификатор доступ принимает значение protected, то все публичные и защищенные члены базового класса становятся защищенными членами производного класса.

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

ПРИМЕР

#include <iostream.h>
class X {
protected: int i;
}
class Y: private X {...};// i  преобразовано к частному члену Y
class Z: public Y {public:void f();};
//поскольку i является частным для Y, оно не может наследоваться в Z (не создается иерархии объектов)
void Z::f(){ i = 2;}//  данная функция не работает т.к. i не доступна

Агрегация или включение – это когда членом одного класса становится объект другого:

Пример использования включения:

Пусть класс D имеет член класса B.

class D
{
public:
  B b;
  ...
};

В свою очередь класс B имеет член класса C.

class В
{
public:
  С с;
  ...
};

Таким образом, используя включение мы строим иерархию объектов. С точки зрения проектирования закрытое наследование равносильно включению, если не считать вопроса с замещением функци

В общем случае между включением и наследованием(не закрытым) есть принципиальная разница:

Включение — это отношение has a (имеет).Используя включение мы строим иерархию объектов.

Наследование — это отношение is a (является). Используя наследование (не закрытое), мы сторим иерархию классов.

Пример (для понимания): автомобиль имеет руль, колеса и т.д. и т.п.

И автомобиль является транспортным средством.

Есть несколько сценариев, когда стоит применять закрытое наследование вместо включения:

  1. Необходимо переопределение абстрактных и/или виртуальных методов.

  2. Необходимо использовать экземпляр наследника полиморфным образом в ограниченном окружении (например, в дружественной функции). Но в общем смысле отношение ЯВЛЯЕТСЯ между наследником и базовым классом отсутствует.

  3. При закрытом наследовании, наследник может обращаться к защищенным членом базового класса.

  4. Закрытое наследование позволяет реализовать "сужающее" наследование. Когда наследник содержит лишь несколько методов базового класса (путем поднятия види-мости с помощью using Base::ProtectedMethod).

Если все это нужно, то закрытое наследование будет более предпочтительнее включения.

Пример:

class  A
{
public: void  PublicFoo()  {}
        virtual  void  VirtualPublicFoo() {}
protected: void  ProtectedFoo()  {}
private: void  PrivateFoo()  {}
};

class  B  :  private  A
{
friend  void CrazyPolymorphicMethod(const  A*  a);
public: using  A::ProtectedFoo;
        void  Foo(){ //  Поднимаем  видимость  одного из  методов  базового  класса
                    ProtectedFoo();//  Вызываем  закрытый  метод!
                    CrazyPolymorphicMethod(this);//  Пример  ограниченного полиморфизма
                     }
private: virtual  void  VirtualPublicFoo()
          override{/*  Переопределяем  виртуальный метод!*/}
};

void  CrazyPolymorphicMethod(const  A* a)
{/**/}

results matching ""

    No results matching ""