类的重用(包含、嵌套、继承)
类的重用(包含、嵌套、继承)
思想
继承关系
is-a(是)/is-a-kind-of(是一种)
- 描述:is-a关系,即派生类对象也是一个基类对象,可以对基类对象执行的任何操作也可以对派生类对象执行
 - 举例:香蕉是水果
 - 实现:is-a最常用,也是使用最常用的公有继承实现
 - 补充:这种关系称为
is-a-kind-of更准确,但通常使用属于is-a 
has-a(包括有)
- 举例:午餐中包括米饭,但米饭不是午餐
 - 实现:一般将一个对象作为另一个的数据成员(包含),或使用私有继承
 - 不能实现:公有继承不能建立这种关系
 
is-like-a(像一种)
- 举例:律师像鲨鱼,但律师不是鲨鱼
 - 不能实现:公有继承不能建立这种关系
 
is-implemented-as-a(作为...来实现)
- 举例:可以用数组来实现栈,但栈不是数组
 - 不能实现:公有继承不能建立这种关系
 
uses-a(使用)
- 举例:计算机可以使用激光打印机
 - 实现:可以使用友元函数或友元类
 - 不能实现:公有继承不能建立这种关系
 
比较(has-a关系,包含和私有继承区别与选择)
区别
- 初始化基类组件 
- 包含:创建类的实例对象
 - 私有继承:构造函数需要使用成员初始化列表来构造基类对象
 
 - 访问基类的方法 
- 包含:使用对象名和句点运算符调用方法,如
m_a.fn(); - 私有继承:使用类名和作用域解析运算符来调用方法,如
A::fn(); 
 - 包含:使用对象名和句点运算符调用方法,如
 - 访问基类对象(使用基类对象本身) 
- 包含:返回对象成员即可,如
return m_a; - 私有继承:使用强制类型转换(派生类转换为基类)再返回,如
return (const APerent &) *this; 
 - 包含:返回对象成员即可,如
 - 访问基类的友元函数 
- 包含:直接使用,如
cout m_a; - 私有继承:使用强制类型转换(派生类转换为基类)再使用,如
cout << (const APerent &) a; 
 - 包含:直接使用,如
 
选择
- 总结 
- 通常使用包含来建立has-a关系
 - 如果新类需要访问原有类的保护成员,或需要重新定义虚函数时,使用私有继承
 
 - 选用包含:大多数C++程序员倾向于使用包含 
- 包含易于理解、而继承较为抽象
 - 继承会引发很多问题,比如多重继承的一些问题
 - 包含能包括多个同类的子对象,而继承只能使用一个这样的对象
 
 - 选用私有继承:私有继承提供的特性更多 
- 私有继承可以访问保护成员
 - 可以重新定义基类中的虚函数(非虚函数也能定义,但如果通过引用来调用则会引发问题,不建议修改非虚函数)
 
 
嵌套类(类 x 类)
简概
- 通过新的类型类作用域类避免名称混乱
 - 旧版本的C++不允许嵌套类或无法完全实现这种概念
 
嵌套类与包含类区别
- 包含:将类对象作为另一个类的成员
 - 嵌套:不创建类成员,而是定义一种类型,而且该类型仅在包含嵌套类声明的类中有效
 
使用场景
- 通常是为了帮助实现另一个类,并避免名称冲突
 
使用
- 声明:class中正常嵌套另一个class声明即可
 - 定义:使用两次作用域解析运算符,如
Queue::Node::Node() {}为嵌套类的构造函数的定义 
访问权限与作用域(和普通变量一样)
声明位置 包含它的类是否可以使用它 从包含它的类派生的类是否可以使用它 在外部是否可以使用它 私有部分 是 否 否 保护部分 是 是 否 公有部分 是 是 是,通过类限定符来使用 
链接到当前文件 0
没有文件链接到当前文件