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.

7
  • 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?) Aug 5, 2020 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++ Aug 5, 2020 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. Aug 5, 2020 at 22:39
  • 2
    This SO answer mentions a real-world example for protected inheritance from boost::compressed_pair.
    – Doc Brown
    Aug 6, 2020 at 5:13

1 Answer 1

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.

2
  • Both examples can be done with private too. Sep 5, 2020 at 21:50
  • CRTP can't be done this way - consider my comment to OP's question
    – davidbak
    Sep 6, 2020 at 1:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.