抽象数据类型和类
类声明的例(续)
矩形类的声明 class Rectangle { private: // 矩形对象的长度和宽度 float length, width; public: // 构造函数 Rectangle(float l = 0, float w = 0); // 存取和修改私有数据的方法 float GetLength(void) const; float PutLength(float l); float GetWidth(void) const; float PutWidth(float w); // 计算并返回矩形的测量值 float Perimeter(void) const; float Area(void) const; };
例 三角矩阵(续)
TriMat类的实现 n 和rowTable的初始化 TriMat ∷TriMat(int matsize) { int storedElements=0; //计数器 ,记录存放元素的个数 // 若 matsize 超出ROWLIMIT,程序退出 if (matsize>ROWLIMIT) { cerr< <”The matrix cannot exceed size” < <ROWLIMIT “x” < <ROWLIMIT < <endl; exit(1); } n =matsize; // 建立数组 rowTable for (int i =0; i <n; i ++) { rowTable[i] =storedElements; storedElements + =n-i; } }
类的实现 在类声明中有若干个方法说明,这些方法必须提供函数来实现。 其代码可在类体中以内部代码形式给出,也可以在类体外给出。 在矩阵类中有一个存取矩阵长度的方法GetLength, 在类体内定义: 在类体外给出: class Rectangle float Rectangle∷GetLength(void) const { { private: return length; //访问私有成员 float length; } float width; public: ······ float GetLength(void) const { return(length); }; ······ };
类声明的例
矩形的ADT
ADT Rectangle is Data 非负实数,给出矩形的长和宽 Operations Constructor Initial values: 矩形的长l和宽w Process: 给矩形的长和宽赋初值 Perimeter Input: 无 Preconditions: 无 Process: 计算矩形的周长 Output: 返回矩形的周长 Postconditions: 无 Area Input: 无 Preconditions: 无 Process: 计算矩形的面积 Output: 返回矩形的面积 Postconditions: 无 end ADT Rectangle
1 0 1 1 0 2 -2 3 2 4 1 5 3 6 5 7 11 8 -6 9
当 n 充分大时,是可以节省比较多的空间(近n/2)。
例 三角矩阵(续)
类TriMat的说明 class TriMat { private: int rowTable[ROWLIMIT]; // M中各行的起始下标 int n; // 行/列数 int M[ELEMENTLIMIT]; // 存放上三角矩阵中的上三角部分元素 public: TriMat(int matsize); void PutElement(double item, int i, int j); //存放数据元素 double GetElement(int i, int j) const; //访问数据元素 void ReadMat(void); //读入矩阵元素 void WriteMat(void) const; //输出矩阵元素 int GetDimension(void) const; //返回矩阵维数 TriMat AddMat(const TriMat& A) const; //矩阵加法 ··· //矩阵其他运算 } 要实现TriMat类就是要把在TriMat类说明中列举的方法(函数)用代码表示出来。
三、抽象数据类型和类
◆ ◆ ◆ ◆
类的基本概念 类构造函数的设计 类函数(方法)的实现 类与其他数据结构的关系
3.1 用户类型类 3.1.1 类的定义 类是用户定义的包含数据项和方法 (函数)的数据类型。 类的成员:数据项和方法。但分为私有(保护)与公共两种不 同的访问级别。 private: 类成员
例 三角矩阵(续)
数组的一大优点是通过下标计算可以直接存取数组元素。 //在数组M中存放矩阵元素Aij void TriMat ∷PutElement(double item, int i, int j) { // 若元素下标越界,退出程序 if ((i<0∣∣i >= n) ∣∣(j<0∣∣j >= n) ) { cerr < <”PutElement: index out of range 0 to “ < <n-1 < <endl; exit(1); } // 忽略对角线以下的所有元素 if (j>=i) M[rowTable[i]+j-i ] =item; }
例 三角矩阵(续)
为此,除用一维数组存放上三角矩阵的上三角部分元素外,再设 计一个行表(rowTable),实质上,也是一个一维数组,其第 i 个 元素存放第 i 行第一个元素在存储数组中的位置。 1 1 0 -2 rowTable 0 2 1 3 0 4 7 9 0 0 5 11 0 0 0 -6 数组M
例 三角矩阵(续)
// 从数组M中取出矩阵元素Aij double TriMat∷GetElement(int i, int j) const { // 若元素下标越界,退出程序 if ((i<0∣∣i >= n) ∣∣(j<0∣∣j >= n) ) { cerr < <”GetElement: index out of range 0 to “ < <n-1 < <endl; exit(1); } if (j >= n) // 元素在对角线之上,返回该元素 return M(rowTable[i]+j -i]; else // 元素在对角线之下,返回数值零 return 0; }
数组的下标计算 计算机的内存实质上是一个一维数组,内存的地址就是数组的下 标。只要建立一个数组的n个下标表达式与“一维数组”的下标 表达式间的映射关系。 设有一个4×3的数组。从地址a开始存储,则A00的地址为 a+0 ×sizeof(M)=a。,第二行的第一个元素应在a+4 × sizeof(M),
构造函数与及其实现 构造函数(constructor) 定义:与类同名的函数称为类的构造函数。 作用:初始化一个或多个数据成员的参数。当没有显式给出参数 时,缺省值为0。 实现:可以在类体的内部或外部实现。 Rectangle∷Rectangle(float l, float w) { length = l; width = w; } 初始化数据成员的其他办法 类名∷类名(参数表): 数据1(参数1), … , 数据at w): length(l), width(w) {}
(数据项、函数)
数据 操作
public:
数据 操作
外部程序单元
类声明
类声明的组成: 类头 保留字class + 类的名称 类体 用花括号{}括起,并以分号结束。 基本形式如下 class 〈类名〉 { private: // 〈私有数据〉 // 〈私有方法声明〉 // …… public: // 〈公有数据〉 // 〈公有方法声明〉 // …… }; 格式要求:数据成员按C++变量格式说明,方法按C++函数格式说 明
例 三角矩阵
矩阵是一种重要的数学工具,在科学和工程计算中有着重要的应 用。用二维数组存放矩阵是非常合适的数据结构。 上三角矩阵的性质:两个上三角矩阵的和、差、积仍是上三角阵。 A00 A01 ··· ··· A0n-1 0 A11 A12 ··· A1n-1 A= 0 0 A22 ··· A2n-1 ··· ··· ··· ··· 0 ··· ··· An-2n-2 An-2n-1 0 0 ··· ··· A-1n-1 三角矩阵的存储 将三角矩阵主对角线及其上面的元素存放在一个数组中,主对角 线下的各项不再被存储。对元素Ai,j,若j<i,元素Ai,j为0,不 再存放在数组中。若j≥i,按行存放在数组中。因此,需要设计 一个存取函数,可通过元素的下标对数组直接存取有关元素。
对n维数组,设M[s1][s2][··· ][sn] ,元素[i1][i2][··· ][in]地址为
a sizeof ( M ) ij
j 1
n
对象及其实现
对象是类类型的变量。通过对象声明(object declaration)产生类类 型的对象 基本格式: 类名 对象(〈参数〉);
对象参数在对象名后的括号内传递给构造函数,初始化有关数 据成员。
Rectangle room(12, 10); //长为12, 宽为10的矩形对象room Rectangle t; //矩形对象 t ,缺省参数为0 对象的公共成员可通过对象名.成员名进行访问。 x = room.Area(); //把room的面积12×10=120赋给x t.PutLength(20); //通过赋值使 t 的长由缺省值0变为20 y = room.length //错误,因为length不是公共成员 变形:类名 对象1(〈参数〉),对象2=对象1,···; Rectangle room(12, 10), yard = room;