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

  const zip = (arr,...arrs)=>arr.map((v,i)=>arrs.reduce((a,arr)=>[...a, arr[i]], [v]))
14
задан Mansfield 6 June 2012 в 23:17
поделиться

3 ответа

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

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

13
ответ дан 1 December 2019 в 13:22
поделиться

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

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";
5
ответ дан 1 December 2019 в 13:22
поделиться

C++ FAQ, Облегченный упоминания о случае, где использование частного наследования является законным решением (См. [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 к защищенному наследованию.

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

1
ответ дан 1 December 2019 в 13:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: