1. 构造函数初始化表
之前的类的构造函数的初始化都是使用赋值=来完成;
对于常量和引用参数,简单的赋值=是不足够的。
1)初始化列表
赋值有显式和隐式赋值两种。
之前的类的初始化如:
现在,采用一种初始化列表:
如上图所示,初始化列表位于构造函数的参数之后,以':'标志,每个变量的初始化采用隐式赋值,变量直接以逗号隔开。
这样,对于常量变量,可以在初始化列表中初始化;
初始化列表常用于复合类和继承。
2. 复合类
现实中,复杂的对象都是由较小和较为简单的对象构成;
由简单对象创建复杂对象的过程称作合成。
合成通常使用在有has-a关系的对象;
通常的基本数据类型可以满足构造简单和小的对象。
为了从小的对象创建复杂的对象,C++提供了复合类-将小的类作为复合类的成员变量。
例如:
Point2D.h
Creature.h:
Main.h:
使用复合类的好处:
A)每个单独的类可以保持相对简单和直观,负责其自己的任务;
B)每个对象可以自包含,更易重用;
C)复合类使用简单的类完成复杂的工作,只需注重子类之间的数据流程。
到底何时适合使用复合类呢?这个没有固定的答案,只需记住每个类应该完成单一的工作。
复合类不需考虑组合子类的实现细节,这些都是子类所关心的。
3. 聚合类
在上一节中,复合类对象的各个子类对象,随着复合类对象的销毁而销毁。
聚合类是复合类中比较特殊的类型,聚合对象和子对象之间没有从属关系;当聚合对象销毁时,子对象并没有销毁。
一个很简单的例子:
一个学校的部门由多个老师构成,并不是说部门拥有(own)了这些老师,她们仅仅是在那里工作;这时,部门可以看作是一个聚合类;
当部门撤销或解散了,老师还是老师,并没有消失;她们还可以分配到其他部门工作。(不像电脑一样,电脑销毁了,内部的CPU、主板等等都销毁了)
在聚合类中,也是将子类加到复合类中,形式是引用或者指针,引用或指向了在类外已经定义的对象;当复合对象销毁了,这些对象依然存在的。
例如:
复合类和聚合类的异同:
复合类:A)可以使用常规变量;B)可以使用指针,如果涉及动态分配和释放内存;C)负责每个子类的创建和销毁;
聚合类:A)通常使用指针执行类外的已存在对象;B)可以使用指向对象的引用值;C)不需要负责每个子类的创建和销毁。
聚合类非常使用,但风险也高;特别要注意内存的分配与释放,预防内存泄漏。
4. 容器类
现实中,容器是最常见的。容器的容量是容器能够存储多少的能力。
类似,容器类是用以装载和组织其他类的实例的。
大多时候用的容器是数组;数组通常提供了动态长度,以及边界检查。
容器类典型应用了标准的最小功能集。
好的定义容器通常包含如下功能:
1)创建一个空的容器;2)插入一个新的元素对象;3)报告当前容器的元素个数;4)清空容器的所有元素;5)提供访问元素的方法;6)排列元素(可选)。
容器类通常分2种:值容器-只包含了对象的拷贝;引用容器-包含了对象的引用。
在C++中,容器通常只包含一种数据类型;
容器是非常有用的,它使编程更容易、安全和快速。
下面是一个典型的例子-数组容器类:
Main.cpp: