Закрытое наследование в C++

292
19 декабря 2016, 19:53

Здравствуйте. Я бы хотел задать вопрос по закрытому наследованию в C++

Как известно если мы пишем

class A {
    // ...
};
class B : private A  {
    // ...
};

То в В мы не сможем обращаться к членам А несмотря на то что А наследуется от В. Но в чем тогда смысл подобных действий если написав вот так:

class A {
    // ...
};
class B  {
  public :
    A a;
};

я смогу внутри В обращаться к членам А, а в первом случае не могу вообще ничего?

Answer 1

В втором случае у вас класс B наследуется от А и содержит поле типа А. То есть, получается, что по факту в B храниться две копии А. К одной доступ есть, к другой нет.

Answer 2

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

  • В случае закрытого наследования, возможно переопределение абстрактных и виртуальных методов.
  • Закрытое наследование позволяет использовать экземпляр наследника полиморфным образом в ограниченном окружении (например, в дружественной функции). Но в общем смысле отношение ЯВЛЯЕТСЯ между наследником и базовым классом отсутствует.
  • При закрытом наследовании, наследник может обращаться к защищенным членом базового класса.
  • Закрытое наследование позволяет реализовать "сужающее" наследование. Когда наследник содержит лишь несколько методов базового класса (путем поднятия видимости с помощью 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)
{
    // 
}
READ ALSO
Простой пример с одним нейроном.

Простой пример с одним нейроном.

Нужен простейший пример с реализацией:

292
Подключение проекта в проект в Visual Studio

Подключение проекта в проект в Visual Studio

Как можно подключить файлы из одного проекта в другой в vs 2010?

319
Несложные Статьи и Книги на Английском [дубликат]

Несложные Статьи и Книги на Английском [дубликат]

На данный вопрос уже ответили:

212