Есть ли примеры, когда нам * нужно * защищенное наследование в C++?

Хотя я видел редкие случаи, когда требовалось наследование частный, я никогда не встречал случая, когда требуется наследование защищенный. Есть у кого-нибудь пример?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
14
0
1 932
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Здесь люди, кажется, ошибаются наследованием защищенного класса и защищенными методами.

FWIW, я никогда не видел, чтобы кто-то использовал наследование защищенных классов, и, если я правильно помню, я думаю, что Страуструп даже считал "защищенный" уровень ошибкой в ​​C++. Вы не сможете сделать очень немногое, если удалите этот уровень защиты и будете полагаться только на общедоступные и частные.

Небольшой комментарий: фамилия мистера С ++ - Страуструп;)

Joe Pineda 10.11.2008 20:03

Господи, сразу исправлю! :)

Mats Fredriksson 11.11.2008 11:55

C++ FAQ Lite упоминает случай, когда использование частного наследования является законным решением (см. [24.3.] Что мне лучше выбрать: композицию или частное наследование?). Это когда вы хотите вызвать производный класс из частного базового класса через виртуальную функцию (в данном случае derivedFunction()):

class SomeImplementationClass
{
protected:
    void service() {
        derivedFunction();
    }

    virtual void derivedFunction() = 0;      

    // virtual destructor etc
};

class Derived : private SomeImplementationClass
{
    void someFunction() {
        service();
    }

    virtual void derivedFunction() {
        // ...
    }

    // ...
};

Теперь, если вы хотите унаследовать от класса Derived и хотите использовать Base::service() из производного класса (скажем, вы хотите переместить Derived::someFunction() в производный класс), самый простой способ добиться этого - изменить частное наследование Base на защищенное наследование.

Извините, не могу придумать более конкретного примера. Лично мне нравится делать все наследование общедоступным, чтобы не тратить время на обсуждение вопроса «должен ли я делать отношения наследования защищенными или закрытыми».

но плакат спросил не об этом, он спросил о защищенном наследовании. Конечно, есть случаи, когда вам нужно частное наследование, хотя и не слишком много.

Matt Price 17.09.2008 17:26

Есть очень редкий вариант использования защищенного наследования. Здесь вы хотите использовать ковариация:

struct base { 
    virtual ~base() {} 
    virtual base & getBase() = 0;
}; 

struct d1 : private /* protected */ base { 
    virtual base & getBase() { 
        return this; 
    } 
}; 

struct d2 : private /* protected */ d1 {
    virtual d1 & getBase () { 
        return this; 
    } 
}; 

Предыдущий фрагмент пытался скрыть его базовый класс и обеспечить контролируемую видимость баз и их функций, по любой причине, с помощью функции "getBase".

Однако в структуре d2 произойдет сбой, поскольку d2 не знает, что d1 является производным от base. Таким образом, covariance работать не будет. Выход из этого - сделать их защищенными, чтобы наследование было видно в d2.

Похожий пример использования этого - когда вы унаследованы от std::ostream, но не хотите, чтобы случайные люди писали в ваш поток. Вы можете предоставить виртуальную функцию getStream, которая возвращает std::ostream&. Эта функция может выполнять некоторую подготовку потока к следующей операции. Например, установка определенных манипуляторов.

std::ostream& d2::getStream() {
    this->width(10);
    return *this;
}

logger.getStream() << "we are padded";

Другие вопросы по теме