权限控制

Public inheritance

public inheritance means "is-a".

If you write that class D (“Derived”) publicly inherits from class B (“Base”), you are telling C++ compilers (as well as human readers of your code) that every object of type D is also an object of type B, but not vice versa.
-- 《Effective C++》item 32

Any function that expects an argument of type Person (or pointer-to-Person or reference-to-Person) will also take a Student object (or pointer-to-Student or reference-to-Student):

void eat(const Person& p); // anyone can eat
void study(const Student& s); // only students study
Person p; // p is a Person
Student s; // s is a Student
eat(p); // fine, p is a Person
eat(s); // fine, s is a Student, and a Student is-a Person
study(s); // fine
study(p); // error! p isn’t a Student

This is true only for public inheritance.

意味着只有公有继承,派生类的指针或引用才能转化为基类指针或引用

Public inheritance asserts that everything that applies to base class objects — everything! — also applies to derived class objects.

Things to Remember
✦ Public inheritance means “is-a.” Everything that applies to base classes must also apply to derived classes, because every derived class object is a base class object.

Private inheritance

Two features:

  1. in contrast to public inheritance, compilers will generally not convert a derived class object (such as Student) into a base class object (such as Person) if the inheritance relationship between the classes is private;
  2. members inherited from a private base class become private members of the derived class, even if they were protected or public in the base class.

see more in https://isocpp.org/wiki/faq/private-inheritance#overview-priv-inherit

Private inheritance means is-implemented-in-terms-of.

If you make a class D privately inherit from a class B, you do so because you are interested in taking advantage of some of the features available in class B, not because there is any conceptual relationship between objects of types B and D. As such, private inheritance is purely an implementation technique. (That’s why everything you inherit from a private base class becomes private in your class: it’s all just implementation detail.)

Private inheritance means that implementation only should be inherited; interface should be ignored.

派生类私有继承基类,旨在利用基类已经写好的一些功能,并不在意基类的接口,继承过来的成员统统变成私有。一般用于software implementation,而非software design.

Things to Remember
✦ Private inheritance means is-implemented-in-terms of. It’s usually inferior to composition, but it makes sense when a derived class needs access to protected base class members or needs to redefine inherited virtual functions.
✦ Unlike composition, private inheritance can enable the empty base optimization. This can be important for library developers who strive to minimize object sizes.

How are “private inheritance” and “composition” similar?

private inheritance is a syntactic variant of composition (AKA aggregation and/or has-a).

E.g., the “Car has-a Engine” relationship can be expressed using simple composition:

class Engine {
public:
  Engine(int numCylinders);
  void start();                 // Starts this Engine
};
class Car {
public:
  Car() : e_(8) { }             // Initializes this Car with 8 cylinders
  void start() { e_.start(); }  // Start this Car by starting its Engine
private:
  Engine e_;                    // Car has-a Engine
};

The “Car has-a Engine” relationship can also be expressed using private inheritance:

class Car : private Engine {    // Car has-a Engine
public:
  Car() : Engine(8) { }         // Initializes this Car with 8 cylinders
  using Engine::start;          // Start this Car by starting its Engine
};

There are several similarities between these two variants:

There are also several distinctions:

Note that private inheritance is usually used to gain access into the protected members of the base class, but this is usually a short-term solution (translation: a band-aid).

What are the access rules with private and protected inheritance?

Take these calsses as examples:

class B                    { /*...*/ };
class D_priv : private   B { /*...*/ };
class D_prot : protected B { /*...*/ };
class D_publ : public    B { /*...*/ };
class UserClass            { B b; /*...*/ };

None of the derived classes can access anything that is private in B.

To make a public member of B public in D_priv or D_prot, state the name of the member with a B:: prefix. E.g., to make member B::f(int, float) public in D_prot, you would say:

class D_prot : protected B {
public:
  using B::f;  // Note: Not using B::f(int,float)
};

Conclusion

  1. 公有继承(public) 公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问。
  2. 私有继承(private) 私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。
  3. 保护继承(protected) 保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。
    see more in C++继承:公有,私有,保护

References

  1. Inheritance — private and protected inheritance