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

StackOverflow https://stackoverflow.com/questions/31867

  •  09-06-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

Люди здесь, похоже, путают защищенное наследование классов и защищенные методы.

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

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

Существует очень редкий случай использования защищенного наследования.Это то место, где вы хотите использовать ковариация:

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".

Однако это приведет к сбою в struct 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";

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() {
        // ...
    }

    // ...
};

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top