|
热门文章
推荐文章
最新文章
|
C++箴言:谨慎使用私有继承(3)
原作者:kuku 添加时间:2007-06-02 原文发表:2007-06-02 人气:19 来源:互联网
本文章共6149字,分4页,当前第3页,快速翻页:
|
首先,你可能要做出允许 Widget 有 derived classes(派生类)的设计,但是你还可能要禁止 derived classes(派生类)重定义 onTick。如果 Widget 从 Timer 继承,那是不可能的,即使 inheritance(继承)是 private(私有)的也不行。(回忆《C++箴言:考虑可选的虚拟函数的替代方法》derived classes(派生类)可以重定义 virtual functions(虚拟函数),即使调用它们是不被允许的。)但是如果 WidgetTimer 在 Widget 中是 private(私有)的而且是从 Timer 继承的,Widget 的 derived classes(派生类)就不能访问 WidgetTimer,因此就不能从它继承或重定义它的 virtual functions(虚拟函数)。如果你曾在 Java 或 C# 中编程并且错过了禁止 derived classes(派生类)重定义 virtual functions(虚拟函数)的能力(也就是,Java 的 final methods(方法)和 C# 的 sealed),现在你有了一个在 C++ 中的到类似行为的想法。
第二,你可能需要最小化 Widget 的 compilation dependencies(编译依赖)。如果 Widget 从 Timer 继承,在 Widget 被编译的时候 Timer 的 definition(定义)必须是可用的,所以定义 Widget 的文件可能不得不 #include Timer.h。另一方面,如果 WidgetTimer 移出 Widget 而 Widget 只包含一个指向一个 WidgetTimer 的 pointer(指针),Widget 就可以只需要 WidgetTimer class(类)的一个简单的 declaration(声明);为了使用 Timer 它不需要 #include 任何东西。对于大型系统,这样的隔离可能非常重要(关于 minimizing compilation dependencies(最小化编译依赖)的细节,参见《C++箴言:最小化文件之间的编译依赖》)。
我早些时候谈及 private inheritance(私有继承)主要用武之地是当一个将要成为 derived class(派生类)的类需要访问将要成为 base class(基类)的类的 protected parts(保护构件),或者希望重定义一个或多个它的 virtual functions(虚拟函数),但是 classes(类)之间的概念上的关系却是 is-implemented-in-terms-of,而不是 is-a。然而,我也说过有一种涉及 space optimization(空间最优化)的极端情况可能会使你倾向于 private inheritance(私有继承),而不是 composition(复合)。
这个极端情况确实非常尖锐:它仅仅适用于你处理一个其中没有数据的 class(类)的时候。这样的 classes(类)没有 non-static data members(非静态数据成员);没有 virtual functions(虚函数)(因为存在这样的函数会在每一个 object(对象)中增加一个 vptr ——参见《C++箴言:多态基类中将析构函数声明为虚拟》);也没有 virtual base classes(虚拟基类)(因为这样的 base classes(基类)也会引起 size overhead(大小成本))。在理论上,这样的 empty classes(空类)的 objects(对象)应该不占用空间,因为没有 per-object(逐对象)的数据需要存储。然而,由于 C++ 天生的技术上的原因,freestanding objects(独立对象)必须有 non-zero size(非零大小),所以如果你这样做,
class Empty {}; // has no data, so objects should
// use no memory
class HoldsAnInt { // should need only space for an int
private:
int x;
Empty e; // should require no memory
};
你将发现 sizeof(HoldsAnInt) >sizeof(int);一个 Empty data member(空数据成员)需要存储。对以大多数编译器,sizeof(Empty) 是 1,这是因为 C++ 法则反对 zero-size 的 freestanding objects(独立对象)一般是通过在 "empty" objects(“空”对象)中插入一个 char 完成的。然而,alignment requirements(对齐需求)可能促使编译器向类似 HoldsAnInt 的 classes(类)中增加填充物,所以,很可能 HoldsAnInt objects 得到的不仅仅是一个 char 的大小,实际上它们可能会扩张到足以占据第二个 int 的位置。(在我测试过的所有编译器上,这毫无例外地发生了。) 本文章更多内容:<<上一页 - 1 - 2 - 3 - 4 - 下一页>> |
 本文章所属分类: 首页
→ 推荐教程
→ C++C语言
C++C语言
|
文章搜索
|