21

I'm C++ newbie, and I have many years of experience about OO languages such as C/C#/Objective-C. Now, I'm learning C++.

I saw this C++ code:

    class World : public State
    {
    };

It seems class World inherits the class State publicly. Public subclassing? It's hard to understand.

What's the concept of this feature? And when is this useful or required?

eonil
  • 83,476
  • 81
  • 317
  • 516
  • Did you mean to write `class World: private State {}`? In what you actually wrote, the inheritance is public. – Steve Jessop Jan 22 '11 at 14:59
  • Did you mean `class World: private State`? – detunized Jan 22 '11 at 14:59
  • @Steve, @detunized I'm sorry for my stupid mistake. I modified the question. – eonil Jan 22 '11 at 15:04
  • 1
    `public` inheritance is the "normal" inheritance as seen e.g. in C# (just to name a language you know), where is the problem? I find much harder to understand `private` inheritance. – Matteo Italia Jan 22 '11 at 15:08
  • @Matteo The problem was I saw the subclassing-access-modifier first time at today, so I had to ensure whether it's concept is equal with what I've expected or not. It was not important it's `public` or `private` :) – eonil Jan 22 '11 at 15:15
  • 1
    @Eonil: uh ok. :) By the way, you *can* omit the inheritance access modifier, but, for classes, it defaults to `private`, which is useless in 99% of situations (for `structs` instead the default is `public`). – Matteo Italia Jan 22 '11 at 15:17
  • Thanks to let me know it. It's hard to believe it's default is `private`. Private subclassing looks really useless in most cases... – eonil Jan 22 '11 at 15:20
  • @Eonil: I think that such default was made for coherence with the default access-specifier for class members (which is `private`), but it really doesn't make sense. It's only use is to make the compiler throw out a lot of errors when you forget to write `public`. `:)` – Matteo Italia Jan 22 '11 at 15:25
  • @Eonil: I don't know, the default access modifier in Java is package protected, it just doesn't apply to inheritance, only to members. C++ at least is erring on the side of encapsulation ;-) – Steve Jessop Jan 22 '11 at 15:28

4 Answers4

24

The need for the public keyword there is just that for classes defined with the keyword class, the default access modifier (for everything - data members, member functions, and base classes) is private. So

class World : State {};

is the same as:

class World : private State {};

and that's probably not what you want - it means that the base class is only accessible within the class World. Outsiders "don't know" that the inheritance is there at all.

For classes defined with the keyword struct, the default access modifier is public, so you could write:

struct World : State {};

and get something that both looks and behaves a bit like every other language with inheritance. But the struct keyword, and the fact that it defines a class, is really only there for compatibility with C. You won't find many C++ style guides that recommend using it just in order to get the default public accessibility - generally it's used only for classes which are POD, or perhaps only for classes with no member functions at all.

As for why C++ has private inheritance in the first place: for most purposes, private inheritance is a form of composition. Normal composition:

class World {
    State state;
  public:
    void foo() {
        state.bar();
        state.baz();
        and so on
    }
};

That is, the class World knows that it's implemented using a State, and the outside world doesn't know how World is implemented.

vs.

class World : private State {
  public:
    void foo() {
        bar();
        baz();
        and so on
    }
};

That is, the class World knows that it's implemented by being a State, and the outside world doesn't know how it's implemented. But you can selectively expose parts of the interface of State by for example putting using State::bar; in the public part of World's definition. The effect is as if you'd laboriously written a function (or several overloads) in World, each of which delegates to the same function on State.

Other than avoiding typing, though, one common use of private inheritance is when the class State is empty, i.e. has no data members. Then if it's a member of World it must occupy some space (admittedly, depending on the object layout this might be space that otherwise would just be padding, so it doesn't necessarily increase the size of World), but if it's a base class then a thing called the "empty base class optimization" kicks in, and it can be zero-size. If you're creating a lot of objects, this might matter. Private inheritance enables the optimization, but the outside world won't infer an "is-a" relationship, because it doesn't see the inheritance.

It's a pretty fine difference - if in doubt just use explicit composition. Introducing inheritance to save typing is all very well until it has some unexpected consequence.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
7

In case

class World: private State
{
};

private inheritance means that all public and protected members of State would be inherited by World and would become private. This seals State inside World. No class that inherits from World will be able access any features of State.

detunized
  • 15,059
  • 3
  • 48
  • 64
3

What makes you think that it's private? It says public right there, which means it is publically subclassing.

That aside, what private and protected inheritance do is the same as public inheritance, except that all the member variables are functions are inherited with at least private or protected accessibility. For example, if State had a public member function 'foo()', it would be private in 'World'.

This is rarely used in practice, but it does have purpose. The most common use that I've seen is composition through inheritance. i.e. you want a "has a" relationship rather than an "is a" (that you usually get with public inheritance). By privately inheriting the class, you get all its variables and methods, but you don't expose them to the outside world.

One advantage of using private inheritance for composition comes from the empty base class optimisation (EBCO). Using normal composition, having a member object of an empty class would still use at least 1 byte because all variables must have a unique address. If you privately inherit the object you want to be composed of then that doesn't apply and you won't suffer memory loss.

e.g.

class Empty { };

class Foo
{
    int foo;
    Empty e;
};

class Bar : private Empty
{
    int foo;
};

Here, sizeof(Foo) will probably be 5, but sizeof(Bar) will be 4 because of the empty base class.

Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • "the same as public inheritance, except that...". The difference is more than just that. In addition, outsiders can't for example static_cast a `World*` to `State*`. – Steve Jessop Jan 22 '11 at 15:08
  • "sizeof(Foo) will probably be 5" - or even worse 8, if `int` is 4-aligned on your implementation. – Steve Jessop Jan 22 '11 at 15:32
1

The public/protected/private keyword before the name of the ancestor class indicates the desired visibility of members from the ancestor. With private inheritance, the descendant inherits only the implementation from the ancestor, but not the interface.

class A {
public:
  void foo();
};

class B : private A {
public:
  void bar();
};

void B::bar()
{
  foo();  // can access foo()
}

B b;
b.foo(); // forbidden
b.bar(); // allowed

In general, you should use public inheritance because inheritance shouldn't be used for implementation re-use only (which is what private inheritance does).

Frederik Slijkerman
  • 6,471
  • 28
  • 39