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





Здесь люди, кажется, ошибаются наследованием защищенного класса и защищенными методами.
FWIW, я никогда не видел, чтобы кто-то использовал наследование защищенных классов, и, если я правильно помню, я думаю, что Страуструп даже считал "защищенный" уровень ошибкой в C++. Вы не сможете сделать очень немногое, если удалите этот уровень защиты и будете полагаться только на общедоступные и частные.
Господи, сразу исправлю! :)
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 на защищенное наследование.
Извините, не могу придумать более конкретного примера. Лично мне нравится делать все наследование общедоступным, чтобы не тратить время на обсуждение вопроса «должен ли я делать отношения наследования защищенными или закрытыми».
но плакат спросил не об этом, он спросил о защищенном наследовании. Конечно, есть случаи, когда вам нужно частное наследование, хотя и не слишком много.
Есть очень редкий вариант использования защищенного наследования. Здесь вы хотите использовать ковариация:
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";
Небольшой комментарий: фамилия мистера С ++ - Страуструп;)