Are there any examples where we *need* protected inheritance in C++? - 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.

Related

Why does C++ allow access restrictions on public inherited base methods?

Regarding the question "How to publicly inherit from a base class but make some of public methods from the base class private in the derived class?", I have a follow-up question:
I can understand that the C++ standard allows a derived class to relax access restrictions of an inherited method, but I can not think of any legitimate use case where it would make sense to impose access restrictions in the derived class.
From my understanding of the concept of inheritance, if class Derived is public class Base, then anything you can do with Base can also be done with Derived. If one does not want Derived to fulfill the interface of Base, one should not use (public) inheritance in the first place. (Indeed, when I encountered this technique in the wild in ROOT's TH2::Fill(double), is was a clear case of inheritance abuse.)
For virtual methods, access restrictions in Derived are also useless, because any user of Derived can use them by casting a Derived* into a Base*.
So, from my limited C++ newbie point of view, these restrictions are misleading (the programmer of Derived might assume that his virtual now-protected method is not called by anyone else, when in fact it might be) and also confuses [me with regard to] what public inheritance should imply.
Is there some legitimate use case I am missing?
From Herb Sutter, Guru of the Week #18:
Guideline #3: Only if derived classes need to invoke the base implementation of a virtual function, make the virtual function protected.
For detail answer, please read my comment in the code written below:
#include <iostream>
#include <typeinfo>
#include <memory>
struct Ultimate_base {
virtual ~Ultimate_base() {}
void foo() { do_foo(); }
protected:
// Make this method protected, so the derived class of this class
// can invoke this implementation
virtual void do_foo() { std::cout << "Ultimate_base::foo"; }
};
struct Our_derived : Ultimate_base {
private:
// Make this method private, so the derived class of this class
// can't invoke this implementation
void do_foo() {
Ultimate_base::do_foo();
std::cout << " Our_derived::foo";
}
};
struct Derive_from_derive : Our_derived {
private:
void do_foo() {
// You can't call below code
// vvvvvvvvvvvvvvvvvvvvvv
// Our_derived::do_foo();
std::cout << " Derive_from_derive::foo";
}
};
// This class is marked final by making its destructor private
// of course, from C++11, you have new keyword final
struct Derive_with_private_dtor : Ultimate_base {
private:
~Derive_with_private_dtor() {}
};
// You can't have below class because its destructor needs to invoke
// its direct base class destructor
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
/*
struct Derive_from_private_dtor : Derive_with_private_dtor {
};
*/
int main() {
std::unique_ptr<Ultimate_base> p = std::make_unique<Our_derived>();
p->foo();
p = std::make_unique<Derive_from_derive>();
p->foo();
p.reset(new Derive_with_private_dtor);
}
From my understanding of the concept of inheritance, if class Derived is public class Base, then anything you can do with Base can also be done with Derived.
This isn't really the concept of inheritance; this is the concept of polymorphism. In particular, this is a statement of the Liskov Substitution Principle. But inheritance can be used for various things in C++ beyond just polymorphism. In fact, anytime your base class has non-virtual methods or data members, you are using it to inject implementation or state into derived classes, not only for polymorphism. If the base class has no virtual methods and no virtual destructor, then the class shouldn't (can't) be used polymorphically. You may use a base class where neither will the base class ever be instantiated, nor will you ever use a pointer to a base. Here's an example:
template <class T>
struct Foo {
T double_this() { return 2 * static_cast<T&>(*this).data; }
T halve_this() { return 0.5 * static_cast<T&>(*this).data; }
};
What does this weird class do? Well, it can be used to inject some interface into any class with a data member called data (and an appropriate constructor):
struct Bar : Foo<Bar> {
Bar(double x) : data(x) {}
double data;
};
Now Bar has methods double and halve. This pattern is called Curiously Recurring Template Pattern (CRTP). Note that we're never going to instantiate Foo<Bar> or have a pointer to it. We just use the interface it provides, non polymorphically.
Now, suppose someone wants to use Foo, but only wants double in their interface but not halve. In this case, it's completely valid to make halve private in the derived. After all, the derived class is just some particular, non polymorphic type, that does not need to conform to any interface other than what the author wants/documents.
Note that when using CRTP, the base class will typically provide public functions, and you'll typically inherit publicly. The entire advantage of CRTP in this use case is that you can inject interface directly; if you were going to make the methods private or inherit privately you'd be better off make Foo<Bar> a member of Bar instead. So it would be more common to make something public into something private, rather than the reverse, in this particular situation.

Multiple-inherited derived class: How to reuse derived functions without repeating calls to base

I am trying to complete some school homework, and I've just noticed there might be a problem caused by reusing a function from a base class in a multiply inherited derived class.
Let's say I have these classes:
class A
class B: public A
class C: public A
class D: public B, public C
Each class has this method:
virtual void read(ifstream& in);
In class B and in class C, the read() function is also calling class A::read():
void B::read(ifstream& in)
{
A::read(in);
/* read method of B*/
}
void C::read(ifstream& in)
{
A::read(in);
/* read method of C*/
}
Now, the problem is, that when I want to make a read() function for class D, I'm actually calling A::read() twice:
void D::read(ifstream& in)
{
B::read(in);
C::read(in);
/* read method of D*/
}
I know I can use the option of using the A::read() only in one class (B or C), but let's say I need to use it in both classes.
This is an example of why multiple inheritance, especially from a common ancestor, is discouraged. Not because it's always bad - though it often is!- but more because it's usually difficult. If you can find an alternative, that's often preferable. Not necessarily. I'm sure you'll ponder this and decide if it's the best design. But for now, we're here to look at ways to avoid repeating A::read() and other pitfalls.
I start with an analogy to the famous Dreaded Diamond of Doom - not anywhere near as dread-worthy as legend suggests, but worth bearing in mind. It's illustrative that when working around the 'duplicated base members' problem created by such a diamond-shape inheritance hierarchy, by using virtual inheritance - the derived class now becomes fully responsible for calling all constructors of all of its virtual bases. Constructor calls don't chain upwards like normal, and data member initialisation is weird. Google it!
N.B. You should use virtual inheritance if the top class of your diamond-shaped hierarchy has any data members, to avoid duplicating/introducing ambiguity for them, too. That's what it's for. But back to the main topic where I use it as an analogy to functions (which don't strictly require it).
The idea is to take inspiration from virtual inheritance's requirement for the final class to manually call virtual bases' constructors, by handling derived classes' read() behaviours the same way: Avoid repeated calls by making each of your derived classes' public-facing read() methods fully responsible for calling all base ones. This also gives you fine control over not only which of the bases' methods are called - but also of their order.
How? We can factor out the real work of each derived read() to protected 'implementation' functions in each class, and provide public overridden 'wrapper functions' in each final class. The wrapper functions will then be responsible for calling their respective class's impl and that of any required bases, in whichever order you want:
class A {
protected:
void read_impl(ifstream &in) { /* A-specific stuff */ }
public:
virtual void read(ifstream &in)
{
read_impl(in);
}
};
class B: public A { // N.B. virtual public if A has data members!
protected:
void read_impl(ifstream &in) { /* B-specific stuff */ }
public:
virtual void read(ifstream &in)
{
A::read_impl(in);
read_impl(in); // B
}
};
class C: public A {
protected:
void read_impl(ifstream &in) { /* C-specific stuff */ }
public:
virtual void read(ifstream &in)
{
A::read_impl(in);
read_impl(in); // CMy
}
};
class D: public B, public C {
protected:
void read_impl(ifstream &in) { /* D-specific stuff */ }
public:
virtual void read(ifstream &in)
{
A::read_impl(in);
B::read_impl(in); // avoids calling A again from B
C::read_impl(in); // ditto from C
read_impl(in); // D
}
};
With this, you gain complete control over what base stuff each final class dones, and when, without unwanted repeated calls. In terms of DRY, impl functions mean no repetition of behavioural code is done for intermediate classes: the writing in each derived read() is all useful declarative information about how they orchestrate bases' behaviours. You can also add extra stuff between, etc.
A very non-generic way to fix this issue is with booleans, just a switch for each class (B && C) to state if I should call my super class's function.
Another way to fix it is just not to call A's function in B or C.

private inheritance in C++

I am learning the concepts of OOPS, and came across private inheritance. From what I've learnt - When a class derives from a base class and letter when the derived class is instantiated, the constructor of the Base class is called first, followed by the constructor of the derived class. So, in the code "A created" would be printed first.
The problem is since the inheritance is private, all the members of A would be private inside B, so how can the constructor of A be called when B is instantiated. Going by this logic, the following code should generate errors, but when I run it, it compiles fine, and gives the output "A created" followed by "B created".
How is this happening? Or am I making some mistake in understanding the concept?
#include <iostream>
using namespace std;
class A{
public:
A(void)
{
cout<<"A created"<<endl;
}
~A()
{
//do nothing
}
void doSomething(void)
{
cout<<"hi";
}
};
class B:private A
{
public:
B(void)
{
cout<<"B created"<<endl;
}
~B()
{
//do nothing
}
};
int main() {
B* myptr = new B();
//myptr->doSomething();
delete myptr;
return 0;
}
B can call public (and protected) methods of A, since A constructor is public B can call it.
Please see following link to better understand c++ private inheritance:
Difference between private, public, and protected inheritance
The access specifier for inheritance limits access to code outside the derived class; think to the base class A as if it were a normal private field:" the outside" can't see it, but B can use it freely from "the inside".
As for the constructor, it's implicitly called by B's constructor, so there's no problem (and, besides, otherwise private inheritance would be unusable).
Still, don't worry too much about private inheritance, it's useful in extremely rare cases (I've never seem it actually used in real life, and for this reason many languages don't even support it), normally composition (using a normal private field) is a better and simpler way.
Here is good short article about private inheritance which illustrates in details what is private inheritance, when it is useful and when it should be avoided in favour of inclusion.
In short:
Inheritance access modifier limits access to basic class properties and methods not for derived class but for code which uses derived class.
This is useful to 'replace' (not 'extend') basic class interface for users of inherited class.
In general it's considered better to include basic class member rather than use private inheritance.
If you need to reuse some methods of basic class which rely on virtual functions and you need to override virtual functions (but you still want to hide part of basic class interface from external code), this is more appropriate case for private inheritance.
Hope this will help.

Correct behavior using virtual methods

Suppose I have a pure virtual method in the base interface that returns to me a list of something:
class base
{
public:
virtual std::list<something> get() = 0;
};
Suppose I have two classes that inherit the base class:
class A : public base
{
public:
std::list<something> get();
};
class B : public base
{
public:
std::list<something> get();
};
I want that only the A class can return a list<something>, but I need also to have the possibility to get the list using a base pointer, like for example:
base* base_ptr = new A();
base_ptr->get();
What I have to do?
Have I to return a pointer to this list? A reference?
Have I to return a null pointer from the method of class B? Or have I to throw an exception when I try to get the list using a B object? Or have I to change the base class method get, making it not pure and do this work in the base class?
Have I to do something else?
You have nothing else to do. The code you provide does exactly that.
When you get a pointer to the base class, since the method was declared in the base class, and is virtual, the actual implementation will be looked up in the class virtual function table and called appropriately.
So
base* base_ptr = new A();
base_ptr->get();
Will call A::get(). You should not return null from the implementation (well you can't, since null is not convertible to std::list< something > anyway). You have to provide an implementation in A/B since the base class method is declared pure virtual.
EDIT:
you cannot have only A return an std::list< something > and not B since B also inherits the base class, and the base class has a pure virtual method that must be overriden in the derived class. Inheriting from a base class is a "is-a" relationship. The only other way around I could see would be to inherit privately from the class, but that would prevent derived to base conversion.
If you really don't want B to have the get method, don't inherit from base.
Some alternatives are:
Throwing an exception in B::get():
You could throw an exception in B::get() but make sure you explain your rationale well as it is counter-intuitive. IMHO this is pretty bad design, and you risk confusing people using your base class. It is a leaky abstraction and is best avoided.
Separate interface:
You could break base into separate interface for that matter:
class IGetSomething
{
public:
virtual ~IGetSomething() {}
virtual std::list<something> Get() = 0;
};
class base
{
public:
// ...
};
class A : public base, public IGetSomething
{
public:
virtual std::list<something> Get()
{
// Implementation
return std::list<something>();
}
};
class B : public base
{
};
The multiple inheritance in that case is OK because IGetSomething is a pure interface (it does not have member variables or non-pure methods).
EDIT2:
Based on the comments it seems you want to be able to have a common interface between the two classes, yet be able to perform some operation that one implementation do, but the other doesn't provide. It is quite a convoluted scenario but we can take inspiration from COM (don't shoot me yet):
class base
{
public:
virtual ~base() {}
// ... common interface
// TODO: give me a better name
virtual IGetSomething *GetSomething() = 0;
};
class A : public Base
{
public:
virtual IGetSomething *GetSomething()
{
return NULL;
}
};
class B : public Base, public IGetSomething
{
public:
virtual IGetSomething *GetSomething()
{
// Derived-to-base conversion OK
return this;
}
};
Now what you can do is this:
base* base_ptr = new A();
IGetSomething *getSmthing = base_ptr->GetSomething();
if (getSmthing != NULL)
{
std::list<something> listOfSmthing = getSmthing->Get();
}
It is convoluted, but there are several advantages of this method:
You return public interfaces, not concrete implementation classes.
You use inheritance for what it's designed for.
It is hard to use mistakenly: base does not provide std::list get() because it is not a common operation between the concrete implementation.
You are explicit about the semantics of GetSomething(): it allows you to return an interface that can be use to retrieve a list of something.
What about just returning an empty std::list ?
That would be possible but bad design, it's like having a vending machine that can give Coke and Pepsi, except it never serves Pepsi; it's misleading and best avoided.
What about just returning a boost::optional< std::list< something > > ? (as suggested by Andrew)
I think that's a better solution, better than returning and interface that sometimes could be NULL and sometimes not, because then you explicitly know that it's optional, and there would be no mistake about it.
The downside is that it puts boost inside your interface, which I prefer to avoid (it's up to me to use boost, but clients of the interface shouldn't have to be forced to use boost).
return boost::optional in case you need an ability to not return (in B class)
class base
{
public:
virtual boost::optional<std::list<something> > get() = 0;
};
What you are doing is wrong. If it is not common to both the derived classes, you should probably not have it in the base class.
That aside, there is no way to achieve what you want. You have to implement the method in B also - which is precisely the meaning of a pure virtual function. However, you can add a special fail case - such as returning an empty list, or a list with one element containing a predetermined invalid value.

When should you restrict accessibility to a virtual function in a derived class?

Consider the following code:
class Base
{
public:
virtual void Foo() {}
};
class Derived : public Base
{
private:
void Foo() {}
};
void func()
{
Base* a = new Derived;
a->Foo(); //fine, calls Derived::Foo()
Derived* b = new Derived;
// b->Foo(); //error
static_cast<Base*>(b)->Foo(); //fine, calls Derived::Foo()
}
I've heard two different schools of thought on the matter:
Leave accessibility the same as the base class, since users could use static_cast<Derived*> to gain access anyway.
Make functions as private as possible. If users require a->Foo() but not b->Foo(), then Derived::Foo should be private. It can always be made public if and when that's required.
Is there a reason to prefer one or the other?
Restricting access to a member in a subtype breaks the Liskov substitution principle (the L in SOLID). I would advice against it in general.
Update: It may "work," as in the code compiles and runs and produces the expected output, but if you are hiding a member your intention is probably making the subtype less general than the original. This is what breaks the principle. If instead your intention is to clean up the subtype interface by leaving only what's interesting to the user of the API, go ahead and do it.
Not an answer to your original question, but if we are talking about classes design...
As Alexandrescu and Sutter recommend in their 39th rule, you should prefer using public non-virtual functions and private/protected virtual:
class Base {
public:
void Foo(); // fixed API function
private:
virtual void FooImpl(); // implementation details
};
class Derived {
private:
virtual void FooImpl(); // special implementation
};
This depends on your design, whether you want to access the virtual function with a derived class object or not.
If not then yes, it's always better to make them private or protected.
There is no code execution difference based on access specifier, but the code becomes cleaner.
Once you have restricted the access of the class's virtual function; the reader of that class can be sure that this is not going to be called with any object or pointer of derived class.