第10章 模板与泛型编程 编程题#2:模板类编写
2026/6/11 7:26:54 网站建设 项目流程

编程题#2:模板类编写

编写模板类Matrix,支持任意数据类型的矩阵,重载+,-,*,=,==,[]等操作。利用int,double, 类complex(包含实数real,虚数virt两部分) 等数据类型测试所写matrix类接口。

template<classT>classsquare_matrix{protected:Tp val[max_size][max_size];intsidelen;// sidelen ≤ 12public:square_matrix(intr,intc);/* … */};

Solution

分析

要求设计一个方阵类型并重载运算符。

根据基础的线性代数知识,一种比较符合大家感性认识的运算符重载设计如下:

  • ++=--=:矩阵加法、矩阵减法,无需多说。
  • **=:可以是矩阵乘法,也可以是矩阵的数乘
  • //=:矩阵除以一个数
  • ^^=:矩阵的幂次
  • ++--:有些人倾向于将“矩阵++/- -”理解为加上或减去单位矩阵,也有人倾向于理解为所有元素加上或减去 1。
  • []:重载下标运算符,直接调取对应位置的元素即可。

代码

#include<iostream>#include<iomanip>usingnamespacestd;template<typenameTp>classsquare_matrix{public:// Construct the matrix by a known side length value(no greater than 12).square_matrix(intlen):sidelen(len){memset(val,0,sizeof(val));}square_matrix(square_matrix<Tp>&another){this->sidelen=another.sidelen;memcpy(this->val,another.val,sizeof(this->val));}square_matrix<Tp>&operator=(square_matrix<Tp>another){this->sidelen=another.sidelen;memcpy(this->val,another.val,sizeof(this->val));return*this;}private:// Maximum size of the matrix.// The calculation rely on recursion so the side length of the matrix cannot be too large.// Calculation will take a very long time to finish if side length is greater than 12.staticconstintmax_size=12;// The matrix and its real side length.Tp val[max_size][max_size];intsidelen;// sidelen ≤ 12private:// Use Laplace's expansion method to calculate determinant.// This function is not allowed to call from outside.Tplaplace_expansion(intr,intc);public:// Modify matrix size.voidmodify_size(intnewlen){sidelen=newlen;}// Modify specific value.voidmodify_value(introw,intcol,Tp value){this->val[row][col]=value;}// Inputvoidinput(void){for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)cin>>val[i][j];}// Get sizeintgetsize(void)const{returnsidelen;}// Get matrixautogetmatrix(void){returnval;}public:// Use subscript operator to get values.Tp*operator[](introw){returnval[row];}public:// Use plus operator to do plus calculation.square_matrix<Tp>&operator+=(square_matrix<Tp>&another){// Two matrixes have the same side length is expected.if(this->sidelen!=another.sidelen)throwinvalid_argument("Two matrixes should have same side length!");elsefor(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)val[i][j]+=another[i][j];return*this;}square_matrix<Tp>operator+(square_matrix<Tp>&another){// Two matrixes have the same side length is expected.if(this->sidelen!=another.sidelen)throwinvalid_argument("Two matrixes should have same side length!");else{square_matrix<Tp>result(this->sidelen);for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)result[i][j]=val[i][j]+another[i][j];returnresult;}}// Use plus operator to do minus calculation.square_matrix<Tp>&operator-=(square_matrix<Tp>&another){// Two matrixes have the same side length is expected.if(this->sidelen!=another.sidelen)throwinvalid_argument("Two matrixes should have same side length!");elsefor(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)val[i][j]-=another[i][j];return*this;}square_matrix<Tp>operator-(square_matrix<Tp>&another){// Two matrixes have the same side length is expected.if(this->sidelen!=another.sidelen)throwinvalid_argument("Two matrixes should have same side length!");else{square_matrix<Tp>result(this->sidelen);for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)result[i][j]=val[i][j]-another[i][j];returnresult;}}// Multiply by a factor.square_matrix<Tp>&operator*=(Tp times)noexcept{for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)val[i][j]*=times;return*this;}square_matrix<Tp>operator*(Tp times)noexcept{square_matrix<Tp>result=*this;for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)result[i][j]*=times;returnresult;}// Divide by a factor.square_matrix<Tp>&operator/=(Tp divisor){if(divisor==0)throwinvalid_argument("Divisor cannot be zero!");elsefor(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)val[i][j]/=divisor;return*this;}square_matrix<Tp>operator/(Tp divisor){if(divisor==0)throwinvalid_argument("Divisor cannot be zero!");else{square_matrix<Tp>result=*this;for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)result[i][j]=val[i][j]/divisor;return*this;}}// operator ++ will be used as adding an identity matrix, which is also known as diag(1,1,...,1).square_matrix<Tp>&operator++()noexcept{for(inti=0;i<=sidelen-1;i+=1)val[i][i]+=1;return*this;}// Operator -- will be used as subtracting an identity matrix.square_matrix<Tp>&operator--()noexcept{for(inti=0;i<=sidelen-1;i+=1)val[i][i]-=1;return*this;}// Matrix multiplesquare_matrix<Tp>operator*(square_matrix<Tp>another){square_matrix<Tp>result(this->sidelen);inti,j,k;for(i=0;i<sidelen;i+=1)for(j=0;j<sidelen;j+=1)for(k=0;k<sidelen;k+=1)result[i][j]+=val[i][k]*another[k][j];returnresult;}square_matrix<Tp>operator*=(square_matrix<Tp>another){square_matrix<Tp>temp(this->sidelen);inti,j,k;for(i=0;i<sidelen;i+=1)for(j=0;j<sidelen;j+=1)for(k=0;k<sidelen;k+=1)temp[i][j]+=val[i][k]*another[k][j];*this=temp;return*this;}public:// Use Laplace's expansion method to calculate determinant.Tpdeterminant(Tp _matrix[12][12],intsize);// Calculate adjugate matrix.// Hint: Inverse matrix multiply by determinant value is adjugate matrix.square_matrix<Tp>adjugate(void);public:voidoutput(){intwidth[12]={0};for(inti=0;i<=sidelen-1;i+=1){for(intj=0;j<=sidelen-1;j+=1){if(i==0)printf("\u250c ");elseif(i==sidelen-1)printf("\u2514 ");elseprintf("\u2502 ");for(j=0;j<sidelen;j+=1)cout<<left<<setw(4)<<val[i][j];if(i==0)printf("\u2510 ");elseif(i==sidelen-1)printf("\u2518 ");elseprintf("\u2502 ");cout<<endl;}}}};intmain(){cout<<__FILE__<<endl;cout<<__TIME__<<endl;cout<<__LINE__<<endl;cout<<_MSVC_LANG<<endl;square_matrix<int>A(2);A.input();square_matrix<int>B=A;(A+A).output();(++A).output();(A*10+B).output();(--A).output();A*=4;A.output();A/=2;A.output();A*=A;A.output();}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询