条款 35: 使公有继承体现"是一个" 的含义
2014-12-31 16:37
260 查看
C++面向对象编程中一条重要的规则是:公有继承意味着"是一个" 。一定要牢牢记住这条规则。
当写下类 D("Derived" )从类 B("Base")公有继承时,你实际上是在告诉编译器(以及读这段代码的人) :类型 D 的每一个对象也是类型 B 的一个对象,但反之不成立;你是在说:B 表示一个比 D 更广泛的概念,D 表示一个比B
更特定概念;你是在声明:任何可以使用类型 B 的对象的地方,类型 D 的对象也可以使用,因为每个类型 D 的对象是一个类型 B 的对象。相反,如果需要一个类型 D 的对象,类型 B 的对象就不行:每个 D "是一个" B
, 但反之不成立。
C++采用了公有继承的上述解释。看这个例子:
在 C++世界中,任何一个其参数为 Person 类型的函数(或 Person 的指针或 Person 的引用)可以实际取一个 Student 对象 (或 Student 的指针或 Student的引用):
只是公有继承才会这样。也就是说,只是 Student 公有继承于 Person 时,C++的行为才会象我所描述的那样。私有继承则是完全另外一回事(见条款42) ,至于保护继承,好象没有人知道它是什么含义。另外,Student
" 是一个"Person 的事实并不说明 Student 的数组"是一个" Person 数组。关于这一话题的讨论参见条款 M3。C++的行为才会象我所描述的那样。
当然,"是一个" 的关系不是存在于类之间的唯一关系。类之间常见的另两个关系是"有一个" 和"用...来实现"。这些关系在条款 40 和 42 进行讨论。这两个关系中的某一个被不正确地表示成" 是一个" 的情况并不少见,这将导致错误的设计。所以,一定要确保自己理解这些关系的区别,以及怎么最好地用C++来表示它们。
当写下类 D("Derived" )从类 B("Base")公有继承时,你实际上是在告诉编译器(以及读这段代码的人) :类型 D 的每一个对象也是类型 B 的一个对象,但反之不成立;你是在说:B 表示一个比 D 更广泛的概念,D 表示一个比B
更特定概念;你是在声明:任何可以使用类型 B 的对象的地方,类型 D 的对象也可以使用,因为每个类型 D 的对象是一个类型 B 的对象。相反,如果需要一个类型 D 的对象,类型 B 的对象就不行:每个 D "是一个" B
, 但反之不成立。
C++采用了公有继承的上述解释。看这个例子:
class Person { ... }; class Student: public Person { ... };
在 C++世界中,任何一个其参数为 Person 类型的函数(或 Person 的指针或 Person 的引用)可以实际取一个 Student 对象 (或 Student 的指针或 Student的引用):
void dance(const Person& p); // 任何人可以跳舞 void study(const Student& s); // 只有学生才学习 Person p; // p 是一个人 Student s; // s 是一个学生 dance(p); // 正确,p 是一个人 dance(s); // 正确,s 是一个学生, // 一个学生"是一个"人 study(s); // 正确 study(p); // 错误! p 不是学生
只是公有继承才会这样。也就是说,只是 Student 公有继承于 Person 时,C++的行为才会象我所描述的那样。私有继承则是完全另外一回事(见条款42) ,至于保护继承,好象没有人知道它是什么含义。另外,Student
" 是一个"Person 的事实并不说明 Student 的数组"是一个" Person 数组。关于这一话题的讨论参见条款 M3。C++的行为才会象我所描述的那样。
当然,"是一个" 的关系不是存在于类之间的唯一关系。类之间常见的另两个关系是"有一个" 和"用...来实现"。这些关系在条款 40 和 42 进行讨论。这两个关系中的某一个被不正确地表示成" 是一个" 的情况并不少见,这将导致错误的设计。所以,一定要确保自己理解这些关系的区别,以及怎么最好地用C++来表示它们。
相关文章推荐
- effective c++ 条款35: 使公有继承体现 "是一个" 的含义
- effective C++笔记之条款35: 使公有继承体现“是一个”的含义
- 条款 40: 通过分层来体现"有一个" 或" 用...来实现"
- 公有继承意味着 "是一个",私有继承意味着"用...来实现(避免切片)"
- Ext的面向对象设计(如何建立一个继承Ext控件的"类")
- effective c++ 条款39: 避免 "向下转换" 继承层次
- 条款 39: 避免"向下转换" 继承层次
- "能做一辈子程序员吗?" —— 做一个越老越辣的程序员
- [System.ComponentModel.DesignerCategory("Code")]的含义
- 看"一个计算机程序员高手的成长"有感
- 写了一个ASP.Net2.0中使用"客户端回调"实现无刷新例子
- Java为什么不支持"无符号型基本数据"---一个无意中的发现!!
- 通过分层来体现 "有一个" 或 "用...来实现"
- 丁丁地图推出一个新服务,"为BLOG添加地图",来玩玩
- ZT:C++中extern "C"含义深层探索
- 一个自认为奇怪的错误。"||"&height 的错误。
- 一个普通男人眼中的"不错的"男人
- (除了一个msgbox什么也没有) directshow之"hello world"第二步
- 一个用于处理分隔","的函数tf_split_str
- 一个美好的开始---"嗨"