今年的高程的C++试题向高手请教试题六
阅读下列说明和C++程序,将应填入__(n)__处的字句写在答题纸的对应栏内.
[程序6说明]
C++语言本身不提供对数组下标越界的判断.为了解决这一问题,在程序6中定义了相应的类模板,使得对于任意类型的二维数组,可以在访问数组元素的同时,对行下标和列下标进行越界判断,并给出相应的提示信息.
[程序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 1,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];
}
~Arraygody(){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 = a2[10][20]; //有越界提示;行下标越界[10]列下标越界[20]
b2 = a2[1][4]; //没有越界提示
}
答案
试题六
(1)classArray<T>
(2)new T[iRsz*iCsz]
(3)throw 'e'
(4)tBody,iCurrentRow=i
(5)tBody(iRsz,iCs2)问题如下:
在template <Class T> class ArrayBody中有一个操作符重载的函数
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 1,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];
}在template <class T> class Array;中有一个函数叫什么我也说不好,我就想问这个函数与上边函数的关系,并且它在程序中怎么使用。ArrayBody<T> & operator[](int i) {
__(4)__;
return tBody;
}谢谢各位了。
阅读下列说明和C++程序,将应填入__(n)__处的字句写在答题纸的对应栏内.
[程序6说明]
C++语言本身不提供对数组下标越界的判断.为了解决这一问题,在程序6中定义了相应的类模板,使得对于任意类型的二维数组,可以在访问数组元素的同时,对行下标和列下标进行越界判断,并给出相应的提示信息.
[程序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 1,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];
}
~Arraygody(){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 = a2[10][20]; //有越界提示;行下标越界[10]列下标越界[20]
b2 = a2[1][4]; //没有越界提示
}
答案
试题六
(1)classArray<T>
(2)new T[iRsz*iCsz]
(3)throw 'e'
(4)tBody,iCurrentRow=i
(5)tBody(iRsz,iCs2)问题如下:
在template <Class T> class ArrayBody中有一个操作符重载的函数
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 1,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];
}在template <class T> class Array;中有一个函数叫什么我也说不好,我就想问这个函数与上边函数的关系,并且它在程序中怎么使用。ArrayBody<T> & operator[](int i) {
__(4)__;
return tBody;
}谢谢各位了。
解决方案 »
- 关于一个文件在硬盘中的全部信息(内详问题),求高人!!!
- msdn中怎么没OpenGL的内容?
- 我想用vc学windows编程,买哪本书好啊?
- 当向ListView添加一行时候,如何在最下边显示和标题对应的待输入的一个空白行
- 怎样在CView中的OnKeyDown()限制字母的输入个数??
- 自己机器上能运行,别人机器上缺dll文件怎么办?
- 怎么用VeCad在MFC中创建cad窗口
- 难死你们——真让人可发一笑,CSDN上竟没有一个人能回答这个问题(愿将825分全部送上)!!!!!!!!
- VC 动态创建的CTreeCtrl,总被下面的CListCtrl遮挡,这个该怎么解决
- 关于ACE+MFC编程遇到的一堆dll连接不一致的问题
- 用loadImage动态导入Icon的release版问题!
- 关于多个CRectTracker对象的Resize Handle(外面的边框)显示问题?急救!!!
请看对于这样的一个两行两列的Array<int> myIntArray(2,2),对于这样的一个表达式myIntArray[1][2],它相当于(myIntArray.operator[](1)).operator[](2)。它的执行过程如下:
首先调用Array<T>的[]操作符,它表示现在要访问这个数组的第1行,因此4的答案把Array<T>的成员tBody的iCurrentRow(当前要访问的行索引)设置为这个参数(这里是1)(因为在这里Array<T>要访问它的成员ArrayBody<T>类型的私有变量,所以有答案1),返回一个ArrayBody<T>&引用即Array<T>对象的成员tBody的引用;
下一步也就是计算tBody.operator[](2)了。此时的tBody.iCurrentRow已在上一步中被赋值,由此值计算得到要访问的元素:参见ArrayBody<T>重载的[]可以得到,tBody的第1行第2列即tBody.tpBody[1 * iColumns + 2]。
1、友元
2、模板
3、动态内存分配
4、成员的初始化
5、异常处理呵呵, bluwindhrt(风一飞) 兄 分析的透彻,关键是要理理解模板和[]操作符重载。
b1 = a1[1][4]; -> b1 = (a1[1])[4];
首先,a1[1]返回一个ArryBody模板类的一个实例类的实例,下一个[4]返回该类的一个实例感觉你在程序中有些字符打错了,例如:
(4)tBody,iCurrentRow=i
-
(4)tBody.iCurrentRow=i
-
这些字符很关键,会影响理解的!!!
问题一:当执行到 b1 = a1[-5][10]时先执行 value = a1[-5]此时返回的是ArrayBody型的值,能讲一下tpBody指向的数组有多大?iRows,iColumns,iCurrentRow又分别是多少,是a1中的10*20那么大的数组吗?三个参数分别为10,20,-5对吗?
问题二ArrayBody中的T& operator[](int j)是由谁在什么时候调用的。因为问题一中的调用是个重载函数,调用的是Array中的T& operator[](int j),而在ArrayBody的调用中我没有看出来什么地方用到了操作符[]。
谢谢了
问题二;a1[-5]会返回一个tpbody的对象,然后下一个[10]就是调用ArrayBody中的T& operator[](int j),当时j=10.
但第一个问题我还是不能理解,当 new T[value] 中的value 是一个负数的话会发生什么样的事情?
这个程序并没有作出适当的处理,这两个类的构造函数的参数应该是 unsigned int 吧.
iRows,iColumns,在a1被初始化时指定为10,20,并且在a1的整个生存期都是不变的,顾名思义,表示“数组”a1的行数和列数;iCurrentRow表示当前要访问的行,每一次调用Array<T>的[]操作符都会把它设置为调用的参数值。所以你的问题中都是对的。
问题二:
对于b1 = a1[-5][10],完全等同于下面合法的两行:
ArrayBody<int>& temp = a1[-5]; //调用Array<int>的[]操作符,此时temp和a1.tBody是同一对象
b1 = temp[10]; //调用ArrayBody<int>的[]操作符
对于砂子的问题:
new操作符会抛出bad_alloc异常,当它无法分配需要的内存的时候。不过new[]操作符接受的参数类型为size_t,是unsigned int的typedef。不过我猜想如果你调用new int[-1]可能会异常抛出,因为-1会被强制类型转换为一个很大的正整数——大到可能根本无法分配这么大的空间给你哦(是2G的样子吧:P。所以在这里用unsigned int跟int是没有分别的。
在ArrayBody<T> & operator[](int i) {
__(4)__;
return tBody;
}
对于b1 = a1[-5][10],return tBody 返回的值应当是
数组大小为10*20那么,三个参数分别为10,20,-5对吧,可tBody是怎么得到的?是因为ArrayBody是它的友元,不是因为ArrayBody的构造函数已经给tBody的iRows和iColumns赋值,而tpBody->iCurrentRow=i,给iCurrentRow赋值了,换句话说友元有点继承的味道,这里的tBody与b2的是不同的(当然不同了),因为它们对应不同的ArrayBody,它是在什么时候被赋值的?
即当b1确定,在任何时候它的tBody就已经确定了。不知我的理解正确吗。
请看Array<T>的构造函数:
Array(int iRsz,int iCsz):tBody(iRsz,iCs2){ }。
正是在这里,Array<T>对象构造时,会将它的两个参数传给ArrayBody<T>的构造函数,从面构造Array<T>对象的成员tBody(请注意,在此处因为ArrayBody<T>的构造函数只有有参数的一个,所以必须用这种语法构造Array<T>对象。如果你对这种构造函数的定义语法不清楚,你得去看看更为详尽的C++语言基础了)。
而对于iCurrentRow,这个成员是在每次调用Array<T>的[]操作符才赋值的,说白了,它其实只起到个临时变量的作用,跟对象的构造没什么关系。
对于友元,它跟继承沾不上边(想想看:朋友跟父子有什么必然的联系吗?)。它只是跟访问有关。
应该能注意到:ArrayBody<T>里所有的成员变量和构造函数都被声明成私有的。按理说,是不能在该类对象之外访问这些变量的,甚至根本无法构造一个ArrayBody<T>对象,因为它的构造函数都是不可访问的。但友元的存在使这种访问变得可能。
请参看C++语言中关于友元的介绍吧。再啰嗦恐怕被人骂了:这些东西在上百本C++书里说得详细透彻百倍,你在这里磨什么牙呀!!呵呵!