Composition⚓︎
约 885 个字 44 行代码 预计阅读时间 5 分钟
组合(composition):从已存在的对象中构造新的对象,即复用已有的实现。
-
包含 (inclusion) 方式:
- 完全(fully) 包含
- 构造函数和析构函数会被自动调用
- 通过引用(reference) 包含
- 需要手动初始化和销毁对象
- 应用场景:逻辑关系并不是完全的、程序开始时还不清楚对象大小、需要在运行时分配 / 连接资源 ...
- 其他 OOP 语言只能采用这种方式
- 完全(fully) 包含
-
嵌入对象 (embedded objects):
- 所有的嵌入对象都被初始化了
- 当不提供参数时,默认的构造函数(或者自己创建的构造函数)就会被调用
- 构造函数可以有初始化列表
- 任意数量的对象,用逗号分隔
- 可选的
- 提供给子构造函数的参数
- 析构函数会被自动调用
-
public
vsprivate
- 声明嵌入对象为私有的(
private
)是很常见的- 它们是底层实现的一部分
- 新类只有旧类的部分公共接口
- 如果想要让子对象的整个公共接口对新对象而言都是可用的话,那么就声明为公有的(
public
)
- 声明嵌入对象为私有的(
- 所有的嵌入对象都被初始化了
-
模块化(modularization):将整体划分为多个良好定义的部分的过程,每个部分可以独立地被建立和检验,并且能以定义良好的方式与之互动。
Initialization List⚓︎
关于初始化列表(initialization list):
- 能够初始化任意类型的数据
- 伪构造函数调用内建函数
- 没有必要在构造函数体内执行赋值语句
- 初始化的顺序是生命的顺序,并非在列表中的顺序
- 并且以相反的顺序被销毁
-
比较初始化和赋值:
Namespace⚓︎
命名空间(namespace):
- 一种对类、函数和变量等的逻辑上的分组
- 命名空间就是一个类似类的作用域
- 当仅需要命名封装时,更倾向于这种方法
-
作用:
- 控制名称:限制名称的作用域
- 避免名称冲突
-
定义:放在头文件中
-
定义命名空间的函数:使用常规的作用域来实现命名空间的函数
-
使用来自命名空间的名称:使用作用域解析式从命名空间中获取名称,但这样做比较麻烦
-
使用声明
- 为名称引入局部同义词
- 消除冗余的作用域修饰法
-
使用指示符
- 这样使命名空间内所有的名称均可用
- 带来了不少便利
void main() { using namespace std; using namespace MyLib; foo(); Cat c; c.Meow(); cout << "hello" << endl; }
- 但这样可能会带来潜在的歧义(ambiguities) 问题。所以遇到不同的命名空间出现相同名称时,还是要用作用域解析式
-
别名
- 命名空间的名称过短可能会导致冲突
- 名称过长则给使用带来不便
- 所以使用别名来创建实用的名称
- 别名还可以用在版本库中
-
命名空间组合
- 可以使用别的命名空间中的名称组合成新的命名空间
- 使用声明可以解决潜在的冲突
- 显式定义的函数占据更高的优先级
-
命名空间选择
- 通过选择别的命名空间中的特征来组合成新的命名空间
- 可以选择需要的名称而不是全部
-
命名空间是开放的:多个命名空间声明可以被加到相同的命名空间,且命名空间可以分散在多个文件中
评论区
如果大家有什么问题或想法,欢迎在下方留言~