views:

849

answers:

3

While I've seen rare cases where private inheritance was needed, I've never encountered a case where protected inheritance is needed. Does someone have an example?

+11  A: 

People here seem to mistake Protected class inheritance and Protected methods.

FWIW, I've never seen anyone use protected class inheritance, and if I remember correctly I think Stroustrup even considered the "protected" level to be a mistake in c++. There's precious little you cannot do if you remove that protection level and only rely on public and private.

Mats Fredriksson
Just a quick comment: Mr. C++'s surname is Stroustrup ;)
Joe Pineda
Good Lord, I'll fix it immediately! :)
Mats Fredriksson
+1  A: 

C++ FAQ Lite mentions of a case where using private inheritance is a legitimate solution (See [24.3.] Which should I prefer: composition or private inheritance?). It's when you want to call the derived class from within a private base class through a virtual function (in this case derivedFunction()):

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

    virtual void derivedFunction() = 0;      

    // virtual destructor etc
};

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

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

    // ...
};

Now if you want to derive from the class Derived, and you want to use Base::service() from within the derived class (say you want to move Derived::someFunction() to the derived class), the easiest way to accomplish this is to change the private inheritance of Base to protected inheritance.

Sorry, can't think of a more concrete example. Personally I like to make all inheritance public so as to avoid wasting time with "should I make inheritance relation protected or private" discussions.

Antti Sykäri
but that's not what the poster asked about, he asked about protected inheritance. There are certainly cases where you would want private inheritance, albeit not too many.
Matt Price
+4  A: 

There is a very rare use case of protected inheritance. It is where you want to make use of covariance:

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; 
    } 
};

The previous snippet tried to hide it's base class, and provide controlled visibility of bases and their functions, for whatever reason, by providing a "getBase" function.

However, it will fail in struct d2, since d2 does not know that d1 is derived from base. Thus, covariance will not work. A way out of this is deriving them protected, so that the inheritance is visible in d2.

A similar example of using this is when you derive from std::ostream, but don't want random people to write into your stream. You can provide a virtual getStream function that returns std::ostream&. That function could do some preparing of the stream for the next operation. For example putting certain manipulators in.

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

logger.getStream() << "we are padded";
Johannes Schaub - litb