【说明】 C++语言本身不提供对数组下标越界的判断。为了解决这一问题,在程序6中定义了相应的类模板,使得对厂任意类型的二维数组,可以在访问数组元素的同时,对行下标和列下标进行越界判断,并给出相应的提示信息。 #include<iostream.h> template <class T> class Array; template <class T> class ArrayBody { friend (1) T* tpBody; int iRows, iColumns, iCurrentRow; ArrayBody (int iRsz, int iCsz) { tpBody = (2) iRows = iRsz; iColumns =iCsz; iCurrentRow =-1; } public: T& operator[] (int j) { bool row_error, column_error; row_error=column_error=false; try{ if (iCurrentRow < 0 || iCurrentRow >=iRows) row_error=true; if (j < 0 || j >=iColumns) column_error=true; if ( row_error==true || column_error == true) (3) } catch (char) { if (row_error==true) cerr << "行下标越界[" << iCurrentRow << "] "; if (column_error== true ) cerr << "列下标越界[" <<j << "]"; cout << "\n"; } return tpBody[iCurrentRow * iColumns +j]; }; ~ArrayBody ( ) { delete[] tpBody; } }; template <class T> class Array { ArrayBody<T> tBody; public: ArrayBody<T> & operator[] (int i) { (4) return tBody; } Array (int iRsz, int iCsz) : (5) {} }; void main() { Array<int>a1(10,20); Array<double>a2(3,5); int b1; double b2; b1=a1[-5][10]; //有越界提示:行下标越界[-5] b1=a1[10][15]; //有越界提示:行下标越界[10] b1=a1[1][4]; //没有越界提示 b2=a2[2][6]; //有越界提示:列下标越界[6] b2=s2[10][20]; //有越界提示:行下标越界[10]列下标越界[20] b2=a2[1][4]; //没有越界提示 }
参考答案:
解析: (1)class Array<T> (2)new T[iRsz*iCsz] (3)throw ’e’ (注:throw后可以填写任意的字符常数) (4)tBody.iCurrentRow=i (5)tBody (iRsz,iCsz) 分析:(1)的前面是友元关键词friend,但在程序中,没有独立的函数,所以只能是另一个模板类Array,所以(1)应填写class Array<T>。 在类模板ArrayBody的定义中,声明了成员变量T tpBody,且在析构函数中有delete []tpBody,由于在C++中,delete总是和new成对出现的,所以(2)应该使用new对tpBody进行初始化。通过程序中return tpBody[iCurrentRow * iColumns+j]行,可以发现该题中采用的是以一维数组来模拟二维数组的创建。在构造函数有两个参数,分别为行数和列数.所以(2)应填写new T[iRsz * iCsz]。 (3)的前后有try{…}和catch{…}语句序列,这是C料中典型的异常处理搭配语句。由于(3)前面已作处理,当有行下标越界时,置row error=true;当有列下标越界时,置 col error=true。且(3)前面的判断是“row error==true||column error=true”,也就是说只要有行下标越界或是列下标越界就执行(3)。错误处理语句写好放在catch中,catch是当正常程序段发生异常时才执行的,并且这里指明了是catch(char),所以只要在(3)抛出一个char异常,即可进行错误处理。所以(3)应填:throw ’e’(这里可以是任何字符)。 再来看Array类中的两个空。首先看(5),这显然是做一些初始化工作,给其成员变量赋初值,而Array类只有一个成员变量tBody,且tBody是ArrayBody类型的,ArrayBody的构造函数需要传递两个参数,分别代表数组的行和列。因此,(5)应填写tBody (iRsz, iCsz)。 main中实例化Array,而在类Array的构造函数对tBody这个变量进行实例化,这时就以一维数组的形式创建了二维数组。在类Array中口运算符重载函数中返回了一个ArrayBody类,而在ArrayBody也存在着[]运算符重载函数,并且在ArrayBody的重载函数中对行下标和列下标同时进行了检查,且返回了一个T类型,对Array<int>来说就是返回了int,也就是数组的一个元素。那么通过对类ArrayBody的观察,发现在整个 ArrayBody中并没有任何地方对iCurrentRow进行赋值,而在ArrayBody的[]运算符重载中却利用其对数组行下标进行判断,而数组的行下标只在Array的口运算符重载中出现,那么 (4)就应该是对类ArrayBody的成员变量iCurrentRow进行赋值,所以(4)应填入 tBody.iCurrentRow=i。