简体   繁体   中英

Are there any examples where we *need* protected inheritance in C++?

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?

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM