模板和异常的问题
在CSDN上看到这样的问题(文的网址为http://community.csdn.net/Expert/topic/3565/3565571.xml?temp=.4035608):
有代码如下,帮忙填5个空格~~~~~~
01 #include <iostream.h>
02 template <class T> class Array;
03
04 template <Class T> class ArrayBody {
05 friend__(1)__;
06 T* tpBody;
07 int iRows,iColumns,iCurrentRow;
08 ArrayBody(int iRsz,int iCsz){
09 tpBody = __(2)__;
10 iRows = iRsz;iColumns = iCsz;iCurrentRow = -1:
11 }
12
13 public:
14 T& operator[](int j){
15 bool row_error,column_error;
16 row_error = column_error =false;
17 try {
18 if(iCurrentRow < 0 || iCurrentRow >= iRows)
19 row_error = true;
20 if(j<0 ||j>= iColumns)
21 column_error = true;
22 if(row_error == true || column_ error == true)
23 __(3)__;
24 }
25 catch(char){
26 if(row_error == true)
27 cerr << "行下标越界[" << iCurrentRow << "]";
28 if(column_error = true)
29 cerr << "列下标越界[" << j << "]";
30 cout << "\n";
31 }
32 return tpBody[iCurrentRow * iColumns + j];
33 }
34 ~Arraygody(){delete[]tpBody;}
35 };
36
37 template <class T> class Array {
38 ArrayBody<T> tBody;
39 public:
40 ArrayBody<T> & operator[](int i) {
41 __(4)__;
42 return tBody;
43 }
44 Array(int iRsz,int iCsz):__(5)__ { }
45 };
46
47 void main()
48 {
49 Array<int> a1(10,20);
50 Array<double> a2(3,5);
51 int b1;
52 double b2;
53 b1 = a1[-5][10]; //有越界提示:行下标越界[-5]
54 b1 = a1[10][15]; //有越界提示:行下标越界[10]
55 b1 = a1[1][4]; //没有越界提示
56 b2 = a2[2][6]; //有越界提示:列下标越界[6]
57 b2 = a2[10][20]; //有越界提示;行下标越界[10]列下标越界[20]
58 b2 = a2[1][4]; //没有越界提示
59 }
看完题目,这一个考模板的使用和异常捕获的题目。
粗略一看,这里有2个类模板,一个是template <class T> class Array;另一个是template <Class T> class ArrayBody。通过这两个类模板实现一个二位数组的模拟。
从上往下看,显然类模板 ArrayBody是Array的成员(第38行),Array可能要访问ArrayBody的成员(还不能肯定)。暂时可以猜测第一空第5行为的friend为Array<T>,这里用到的类模板或类不多,填这个的可能性比较大。
第二空(第9行)tpBody为一个指针,给我的初步印象就是应该new一个什么,或者是指向什么。暂时还不肯定,先空下来。
看第三空,第25行有个catch(char),显然23行应该是throw('e'),当然不一定是'e',只要是个char就行。
第四空暂时还不知道,第五空肯定是ArrayBody(iRsz,iCsz)。为什么呢?因为这儿显然是要在构造Array之前先构造一个类(或模板),而Array的成员模板(或类)只有 ArrayBody了,应该是这样没错了。
这里模拟的是一个二维数组,看一下49行 Array<int> a1(10,20);当执行这条语句的时候,应该先执行Array的构造函数,而在Array构造函数之前,应该先执行ArrayBody的构造函数,所以最先执行的是ArrayBody(int iRsz,int iCsz),tBody是一个指针,它应该指向什么呢,应该是分配一个空间吧,我首先想到的是 第二空填写 new T[iRsz][iCsz]。
分配好空间后,给各个成员变量赋初值。好,OK,没问题。
同样第50行的代码执行同49行。
到了53行,b1 = a1[-5][10]; 首先执行ArrayBody<T> & operator[](int i),再执行T& operator[](int j),最后返回的是二位数组中指定变量的值。第23行return tpBody[iCurrentRow * iColumns + j];这一点可以看出。奇怪,怎么iCurrentRow好像没有赋初值啊,对!第四空(第41行)应该填写tBody.iCurrentRow。
好,慢着,return tpBody[iCurrentRow * iColumns + j]是个一维数组,那第二空的new T[iRsz][iCsz]是不是应该该成new T[iRsz * iCsz]。
就这样,连猜带蒙填完了。但是还不能保证它的正确性。
现在就需要验证才行。拿54行 b1 = a1[10][15];
1.首先执行ArrayBody<T> & operator[](int i),此时a.tBody.iCurrentRow应该为10;
2.接着执行T& operator[](int j),a.tBody.j应该为15。由于a.tBody.iCurrentRow的值(==10)等于允许的最大行数(iRows == 10,所以a.tBody.iCurrentRow最大只能为9),所以row_error == true , column_ error == false,捕获异常,因而行下标越界。正如程序注视中提示的。所以应该可以认为这个答案是正确的了。
以上是个人观点,错误指出敬请指教!^_^