星球狂想战队|一起来学C++:C++中的代码重用

本章内容包括:
has-a关系;包含对象成员的类;模板类valarray;私有和保护继承;多重继承;虚基类;创建类模板;使用类模板;模板的具体化 。C++的一个主要目标是促进代码重用 。 公有继承是实现这种目标的机制之一 , 但并不是唯一的机制 。 本章将介绍其他方法 , 其中之一是使用这样的类成员:本身是另一个类的对象 。 这种方法称为包含(containment)、组合(composition)或层次化(layering) 。 另一种方法是使用私有或保护继承 。 通常 , 包含、私有继承和保护继承用于实现has-a关系 , 即新的类将包含另一个类的对象 。 例如 , HomeTheater类可能包含一个BluRayPlayer对象 。 多重继承使得能够使用两个或更多的基类派生出新的类 , 将基类的功能组合在一起 。
第10章介绍了函数模板 , 本章将介绍类模板——另一种重用代码的方法 。 类模板使我们能够使用通用术语定义类 , 然后使用模板来创建针对特定类型定义的特殊类 。 例如 , 可以定义一个通用的栈模板 , 然后使用该模板创建一个用于表示int值栈的类和一个用于表示double值栈的类 , 甚至可以创建一个这样的类 , 即用于表示由栈组成的栈 。
14.1包含对象成员的类首先介绍包含对象成员的类 。 有一些类(如string类和第16章将介绍的标准C++类模板)为表示类中的组件提供了方便的途径 。 下面来看一个具体的例子 。
学生是什么?入学者?参加研究的人?残酷现实社会的避难者?有姓名和一系列考试分数的人?显然 , 最后一个定义完全没有表示出人的特征 , 但非常适合于简单的计算机表示 。 因此 , 让我们根据该定义来开发Student类 。
将学生简化成姓名和一组考试分数后 , 可以使用一个包含两个成员的类来表示它:一个成员用于表示姓名 , 另一个成员用于表示分数 。 对于姓名 , 可以使用字符数组来表示 , 但这将限制姓名的长度 。 当然 , 也可以使用char指针和动态内存分配 , 但正如第12章指出的 , 这将要求提供大量的支持代码 。 一种更好的方法是 , 使用一个由他人开发好的类的对象来表示 。 例如 , 可以使用一个String类(参见第12章)或标准C++string类的对象来表示姓名 。 较简单的选择是使用string类 , 因为C++库提供了这个类的所有实现代码 , 且其实现更完美 。 要使用String类 , 您必须在项目中包含实现文件string1.cpp 。
对于考试分数 , 存在类似的选择 。 可以使用一个定长数组 , 这限制了数组的长度;可以使用动态内存分配并提供大量的支持代码;也可以设计一个使用动态内存分配的类来表示该数组;还可以在标准C++库中查找一个能够表示这种数据的类 。
自己开发这样的类一点问题也没有 。 开发简单的版本并不那么难 , 因为double数组与char数组有很多相似之处 , 因此可以根据String类来设计表示double数组的类 。 事实上 , 本书以前的版本就这样做过 。
当然 , 如果C++库提供了合适的类 , 实现起来将更简单 。 C++库确实提供了一个这样的类 , 它就是valarray 。
14.1.1valarray类简介valarray类是由头文件valarray支持的 。 顾名思义 , 这个类用于处理数值(或具有类似特性的类) , 它支持诸如将数组中所有元素的值相加以及在数组中找出最大和最小的值等操作 。 valarray被定义为一个模板类 , 以便能够处理不同的数据类型 。 本章后面将介绍如何定义模板类 , 但就现在而言 , 您只需知道如何使用模板类即可 。
模板特性意味着声明对象时 , 必须指定具体的数据类型 。 因此 , 使用valarray类来声明一个对象时 , 需要在标识符valarray后面加上一对尖括号 , 并在其中包含所需的数据类型:
valarrayq_values;//anarrayofintvalarrayweights;//anarrayofdouble第4章介绍vector和array类时 , 您见过这种语法 , 它非常简单 。 这些类也可用于存储数字 , 但它们提供的算术支持没有valarray多 。


推荐阅读