第9周-任务4-二维数组类

来源:互联网 发布:台湾清华大学知乎 编辑:程序博客网 时间:2024/04/30 22:58

【题目】建立一个二维数组类Douary,使该类中有以下数据成员、成员函数及友员函数,完成矩阵的输入、输出、加、减、相等判断等操作。

给出的代码部分如下:

class Douary{public:Douary(int m, int n);//构造函数:用于建立动态数组存放m行n列的二维数组(矩阵)元素,并将该数组元素初始化为0~Douary(); //析构函数:用于释放动态数组所占用的存储空间。friend istream &operator>>(istream &input, Douary &d);//重载运算符“>>”输入二维数组,d为Dousry类对象;friend ostream &operator<<(ostream &output, Douary &d);//重载运算符“<<”以m行n列形式输出,d为Douary类对象。friend Douary operator+(const Douary &d1,const Douary &d2);//两个矩阵相加,规则:对应位置上的元素相加friend Douary operator-(const Douary &d1,const Douary &d2);//两个矩阵相减,规则:对应位置上的元素相减bool operator==(const Douary &d);//判断两个矩阵是否相等,即对应位置上的所有元素是否相等private:int * Array;      //Array 为动态数组指针。int row;          //row  为二维数组的行数。int col;          //col   为二维数组的列数。}int main(){Douary d1(2,3),d2(2,3)cout<<"输入d1:"<<endl;  cin>>d1;cout<<"输入d2:"<<endl;  cin>>d2;coutt<<"d1="<<endl;    cout<<d1;coutt<<"d2="<<endl;    cout<<d2;coutt<<"d1+d2="<<endl; cout<<(d1+d2);coutt<<"d1-d2="<<endl;cout<<(d1-d2);cout<<"d1"<<((d1==d2)?"==":"!=")<<"d2"<<endl;}

【说明】(1)在上面的成员函数中,少定义了一个复制构造函数。对一般的类而言,这个复制构造函数是默认的,但在此问题中却必须给出。详细讲解请参考:《何时需要自定义复制构造函数?》(2)在初次给出的部分代码中,operate+、operate-和operate==的返回值都是引用型(&)的,这是不合适的。这也是一个值得搞清楚的问题,参考:《函数返回值是否使用引用类型的问题:理解引用、返回值》

【参考解答】

#include <iostream>using namespace std;class Douary{public:Douary(int m, int n);//构造函数:用于建立动态数组存放m行n列的二维数组(矩阵)元素,并将该数组元素初始化为Douary(const Douary &d);//构造函数:用于建立动态数组存放m行n列的二维数组(矩阵)元素,并将该数组元素初始化为~Douary(); //析构函数:用于释放动态数组所占用的存储空间friend istream &operator>>(istream &input, Douary &d);//重载运算符“>>”输入二维数组,其中d为Dousry类对象;friend ostream &operator<<(ostream &output, Douary &d);//重载运算符“<<”以m行n列矩阵的形式输出二维数组,其中d为Douary类对象。friend Douary operator+(const Douary &d1,const Douary &d2);//两个矩阵相加,规则:对应位置上的元素相加friend Douary operator-(const Douary &d1,const Douary &d2);//两个矩阵相减,规则:对应位置上的元素相减bool operator==(const Douary &d);//判断两个矩阵是否相等,即对应位置上的所有元素是否相等private:int * Array;      //Array 为动态数组指针。int row;          //row  为二维数组的行数。int col;          //col   为二维数组的列数。};Douary::Douary(int m, int n) //构造函数:用于建立动态数组存放m行n列的二维数组(矩阵)元素,并将该数组元素初始化为{row=m;col=n;Array = new int[m*n]; //Array只能指向一维数组,将m*n个元素的一维数组当作m行n列的数组看待了for(int i=0; i<row; ++i)for(int j=0; j<col; ++j)Array[i*col+j]=0; //关键是给出各个元素地址的计算办法,此处还可以写作*(Array+i*col+j)=0; }Douary::Douary(const Douary &d){row=d.row;col=d.col;Array = new int[row*col];for(int i=0; i<row; ++i)for(int j=0; j<col; ++j)Array[i*col+j]=d.Array[i*col+j]; //注意地址求法}Douary::~Douary() //析构函数:用于释放动态数组所占用的存储空间{delete [] Array;}istream &operator>>(istream &input, Douary &d)//重载运算符“>>”输入二维数组,其中d为Dousry类对象{for(int i=0; i<d.row; ++i)for(int j=0; j<d.col; ++j)cin>>d.Array[i*d.col+j];//注意地址求法return input;}ostream &operator<<(ostream &output, Douary &d)//重载运算符“<<”以m行n列矩阵的形式输出二维数组,其中d为Douary类对象{for(int i=0; i<d.row; ++i){for(int j=0; j<d.col; ++j)cout<<d.Array[i*d.col+j]<<"\t"; //注意地址求法cout<<endl;}cout<<endl;return output;}Douary operator+(const Douary &d1,const Douary &d2)//两个矩阵相加,规则:对应位置上的元素相加{//在此可以先判断d1和d2的行列是否相同,如果不相同可以报错退出,不做运算。本参考解答忽略了这一前提Douary d(d1.row,d1.col);for(int i=0; i<d1.row; ++i){for(int j=0; j<d1.col; ++j)d.Array[i*d1.col+j]=d1.Array[i*d1.col+j]+d2.Array[i*d1.col+j];}return d;}Douary operator-(const Douary &d1,const Douary &d2)//两个矩阵相减,规则:对应位置上的元素相减{//在此可以先判断d1和d2的行列是否相同,如果不相同可以报错退出,不做运算。本参考解答忽略了这一前提Douary d(d1.row,d1.col);for(int i=0; i<d1.row; ++i){for(int j=0; j<d1.col; ++j)d.Array[i*d1.col+j]=d1.Array[i*d1.col+j]-d2.Array[i*d1.col+j];}return d;}bool Douary::operator ==(const Douary &d)//判断两个矩阵是否相等,即对应位置上的所有元素是否相等{if(row!=d.row||col!=d.col) return false;bool eq = true;for(int i=0; i<row; ++i){for(int j=0; j<col; ++j)if (Array[i*col+j]!=d.Array[i*col+j]) {eq=false;break;}if (!eq) break;}return eq;}int main(){Douary d1(2,3),d2(2,3);cout<<"输入d1(2,3):"<<endl;cin>>d1;cout<<"输入d2(2,3):"<<endl;cin>>d2;cout<<"d1="<<endl;cout<<d1;cout<<"d2="<<endl;cout<<d2;cout<<"d1+d2="<<endl;Douary d3=(d1+d2);cout<<d3;cout<<"d1-d2="<<endl;cout<<(d1-d2);cout<<"d1"<<((d1==d2)?"==":"!=")<<"d2"<<endl;system("pause");return 0;}

  还看见有的同学除了重载输出(ostream &operator<<(ostream &output, Douary &d))时用双重循环外,其余的函数中只用单重循环实现,例如operate+的实现:

Douary operator+(const Douary &d1,const Douary &d2){Douary d(d1.row,d1.col);for(int i=0; i<d1.row*d1.col; ++i){d.Array[i]=d1.Array[i]+d2.Array[i];}return d;}
  这也是一个很好的解决办法,对应位置上的值相加即可。只要输出时让用户看着是二维的样子即可,用户才不关心内部的实现呢。这种“欺里瞒外”的方法值得推荐。这要谴责,原题中要让实现二维数组功能,却偏给出个指向int的指针就已经带头这么干了。


<本文完>

原创粉丝点击