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?
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.