5

C++ supports protected inheritance: A class can derive from a base class B in a way that the "outside" world doesn't see that class "as a B" but the class itself and it's derived classes does see itself "as a B".

struct B {};
struct Klass : protected B {
  // here I am B
};
struct Derived : public Klass {
  // here I am B
};

// ...
Klass k; // k is not a B
Derived d; // d is not a B

(Demo)

Is there any use to this language feature? I'm specifically looking for patterns / functionality which is easy to implement with protected inheritance, but difficult (or "ugly", verbose) without it.

Similar to this question, but none of the answers there really apply here IMO. Interest sparked by this stackoverflow question.

Daniel Jour
  • 683
  • 3
  • 14
  • see [Why do 'some examples' and 'list of things' questions get closed?](https://softwareengineering.meta.stackexchange.com/a/7538/31260) – gnat Aug 05 '20 at 19:45
  • 2
    @gnat I understand that my question is *close* to a "list of" question, but I have a very specific question here: **Is** there any use [..]? (Yes/No). I'd be happy to reformulate the question to better match the requirements of the site, though. (How?) – Daniel Jour Aug 05 '20 at 19:47
  • Furthermore, assuming (based on the linked SO question) that using protected inheritance is not "common", I find it interesting that it hasn't been removed from C++ – Daniel Jour Aug 05 '20 at 19:51
  • 2
    @DanielJour: "*I find it interesting that it hasn't been removed from C++*" That doesn't make any sense. The only reasons to remove a feature are if it is actively *harmful* (see `auto_ptr`) or if there is something *specific* to be gained by its removal (like commas in `[]` that C++20 deprecated). A thing only being rarely used is insufficient justification for ditching a feature. – Nicol Bolas Aug 05 '20 at 22:39
  • 2
    [This SO answer](https://stackoverflow.com/a/1374362) mentions a real-world example for protected inheritance from `boost::compressed_pair`. – Doc Brown Aug 06 '20 at 05:13
  • Swift removed it, and removed friends. There’s private, file private (can be accessed within a source file), internal (public within module) and public (public outside a module). – gnasher729 Aug 06 '20 at 10:45
  • @DocBrown (and others): But consider CRTP - I believe there _are_ important uses for private inheritance from a CRTP-ish base class. Maybe protected as well? Perhaps the CRTP base class implements some service that should only be accessed within the class or derived classes, but not from outside? – davidbak Sep 06 '20 at 01:52

1 Answers1

2

There are (or at least should be) no applications where this feature is actually useful. The reason for this is that the only thing it allows you to do is this:

class A : protected B {
   ...
   void something () { doSomethingThatRequiresB(this); }
};

But this is exactly equivalent to:

class A {
protected:
   B myB;
   ...
   void something () { doSomethingThatRequiresB(&myB); }
};

The latter, however, is easier to understand so is always preferable.

The only caveat is that, per the answer referenced in Doc Brown's comment to the question, it appears in some circumstances (particular if the base class is empty) the former can trigger some optimisations that the latter does not, but at least theoretically they should be the same, and I would consider the lack of optimisation in the latter case a shortcoming of the compiler, not a problem of the code.

occipita
  • 209
  • 2
  • 5