在 C++ 将 public inheritance(公有继承)视为一个 is-a 关系。当给定一个 hierarchy(继承体系),其中有一个 class Student 从一个 class Person 公有继承,当为一个函数调用的成功而有必要时,需要将 Students 隐式转型为 Persons,它通过向编译器展示来做到这一点。用 private inheritance(私有继承)代替 public inheritance(公有继承)把这个例子的一部分重做一下是值得的:
class Person { ... };
class Student: private Person { ... }; // inheritance is now private
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); // error! a Student isn't a Person
很明显,private inheritance(私有继承)不意味着 is-a。那么它意味着什么呢?
“喂!”你说:“在我们得到它的含义之前,我们先看看它的行为。private inheritance(私有继承)有怎样的行为呢?”好吧,支配 private inheritance(私有继承)的第一个规则你只能从动作中看到:与 public inheritance(公有继承)对照,如果 classes(类)之间的 inheritance relationship(继承关系)是 private(私有)的,编译器通常不会将一个 derived class object(派生类对象)(诸如 Student)转型为一个 base class object(基类对象)(诸如 Person)。这就是为什么为 object(对象)s 调用 eat 会失败。第二个规则是从一个 private base class(私有基类)继承的 members(成员)会成为 derived class(派生类)的 private members(私有成员),即使它们在 base class(基类)中是 protected(保护)的或 public(公有)的。
如果 D 从 B 私有继承,它就意味着 D objects are implemented in terms of B objects(D 对象是根据 B 对象实现的),没有更多了。private inheritance(私有继承)在 software design(软件设计)期间没有任何意义,只在 software implementation(软件实现)期间才有。 private inheritance(私有继承)意味着 is-implemented-in-terms-of(是根据……实现的)的事实有一点混乱,正如《通过composition模拟“has-a”》一文中所指出的 composition(复合)也有同样的含义。你怎么预先在它们之间做出选择呢?答案很简单:只要你能就用 composition(复合),只有在绝对必要的时候才用 private inheritance(私有继承)。什么时候是绝对必要呢?主要是当 protected members(保护成员)和/或 virtual functions(虚拟函数)掺和进来的时候,另外还有一种与空间相关的极端情况会使天平向 private inheritance(私有继承)倾斜。我们稍后再来操心这种极端情况。
我们决定修改 Widget class 以持续跟踪每一个 member function(成员函数)被调用了多少次。在运行时,我们可以周期性地检查这一信息,与每一个 Widget 的这个值相伴的可能还有我们觉得有用的其它数据。为了进行这项工作,我们需要设立某种类型的 timer(计时器),以便在到达收集用法统计的时间时我们可以知道。