Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ subclassing access modifier?

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?

like image 333
eonil Avatar asked Jan 22 '11 14:01

eonil


People also ask

What are the C access specifiers?

In C++, there are three access specifiers: public - members are accessible from outside the class. private - members cannot be accessed (or viewed) from outside the class. protected - members cannot be accessed from outside the class, however, they can be accessed in inherited classes.

What are the 4 access modifiers in C#?

C# provides four types of access modifiers: private, public, protected, internal, and two combinations: protected-internal and private-protected.

Are access modifiers same in Java and C++?

This is little bit analogous to "package" field modifier in Java (default field modifier), except that in C++ a friendship gives access to all private members, but in Java the access from classes in the same package is specific for a class field. There are not only friend classes but also functions.

Does C support access modifiers?

In C++, there are 3 access modifiers: public. private. protected.


2 Answers

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.

like image 193
Steve Jessop Avatar answered Oct 14 '22 06:10

Steve Jessop


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.

like image 45
detunized Avatar answered Oct 14 '22 07:10

detunized