矩陣類的模板實現(C++)

矩陣類 -- tigerwood -- 編程愛好者博客/***設計一個矩陣(摸板)類Matrix,實現矩陣的輸入和輸出(重載>>和<<),重載拷貝構造函數,賦值運算和函數調用運算符()實現矩陣的轉置!、加、減、乘和求負-,必須處理各種異常(越界、下標錯誤、不匹配等)然後編寫主函數進行全面的測試。*********************//****************************************************************************************************/#include<iostream>#include<conio.h>//getch原型usingnamespacestd;//空間申請異常類classWrongmem{};//下標越界異常類classOutofrange{};//定義錯誤異常類classDiffer{};/*********************************矩陣類開始**************************************/constintMAX_SIZE=1000;template<classT>classMatrix{public://兩參數構造函數Matrix(intr,intc):rows(r),cols(c){if(rows>MAX_SIZE||rows<1||cols>MAX_SIZE||cols<1)throwOutofrange();mem=newT[rows*cols];if(mem==NULL)throwOutofrange();}//四參數構造函數Matrix(intr,intc,T*data,intsize=0):rows(r),cols(c){if(rows>MAX_SIZE||rows<1||cols>MAX_SIZE||cols<1)throwOutofrange();if(size&&size<sizeof(rows*cols)/sizeof(int))throwOutofrange();mem=newT[rows*cols];if(mem==NULL)throwWrongmem();for(inti=0;i<rows*cols;i++)mem[i]=data[i];}//析構函數~Matrix(){delete[]mem;}Tsetrows()const{returnrows;}Tsetcols()const{returncols;}//修改矩陣voidsetMatrix(T*data,intsize);voidsetMatrix(T*data);//重載函數調用運算符()T&operator()(inti,intj);//拷貝構造函數Matrix(constMatrix<T>&x);//重載賦值運算符Matrix<T>operator=(Matrix<T>&x);//重載轉置!Matrix<T>operator!();//重載+Matrix<T>operator+(constMatrix<T>&x);//重載-Matrix<T>operator-(constMatrix<T>&x);//重載*Matrix<T>operator*(constMatrix<T>&x);//重載求負-Matrix<T>operator-();private:T*mem;constintrows,cols;};/**************************函數實現**********************************///修改矩陣template<classT>voidMatrix<T>::setMatrix(T*data,intsize){if(rows*cols>size)throwOutofrange();for(inti=0;i<size;i++)mem[i]=data[i];}template<classT>voidMatrix<T>::setMatrix(T*data){for(inti=0;i<rows*cols;i++)mem[i]=data[i];}//重載函數調用運算符()template<classT>T&Matrix<T>::operator()(inti,intj){if(i>=rows||j>=cols)throwOutofrange();elsereturnmem[i*cols+j];}//重載輸入運算符template<classT>istream&operator>>(istream&in,Matrix<T>&x){for(inti=0;i<x.setrows();i++){for(intj=0;j<x.setcols();j++)in>>x(i,j);}returnin;}//重載輸出<<template<classT>ostream&operator<<(ostream&out,Matrix<T>&x){for(inti=0;i<x.setrows();i++){for(intj=0;j<x.setcols();j++)out<<x(i,j)<<"";out<<endl;}out<<endl;returnout;}//拷貝構造函數template<classT>Matrix<T>::Matrix(constMatrix<T>&x):rows(x.rows),cols(x.cols){mem=newT[rows*cols];if(mem==NULL)throwDiffer();elsefor(inti=0;i<x.rows*x.cols;i++)mem[i]=x.mem[i];}//重載附值運算符=template<classT>Matrix<T>Matrix<T>::operator=(Matrix<T>&x){if(rows!=x.rows||cols!=x.cols)throwDiffer();if(this!=&x){delete[]mem;mem=newT[rows*cols];if(mem==NULL)throwWrongmem();elsefor(inti=0;i<x.rows*x.cols;i++)mem[i]=x.mem[i];}return*this;}//重載轉置!template<classT>Matrix<T>Matrix<T>::operator!(){Matrix<T>temp(cols,rows);for(inti=0;i<cols;i++)for(intj=0;j<rows;j++)temp(i,j)=(*this)(j,i);returntemp;}//重載+template<classT>Matrix<T>Matrix<T>::operator+(constMatrix<T>&x){inti;if(rows!=x.rows||cols!=x.cols)throwDiffer();Matrix<T>temp(*this);if(rows==x.rows&&cols==x.cols){for(i=0;i<rows*cols;i++)temp.mem[i]=mem[i]+x.mem[i];returntemp;}elsethrowDiffer();}//重載-template<classT>Matrix<T>Matrix<T>::operator-(constMatrix<T>&x){inti;if(rows!=x.rows||cols!=x.cols)throwDiffer();Matrix<T>temp(*this);if(rows==x.rows&&cols==x.cols){for(i=0;i<rows*cols;i++)temp.mem[i]=mem[i]-x.mem[i];returntemp;}elsethrowDiffer();}//重載矩陣乘法運算符*template<classT>Matrix<T>Matrix<T>::operator*(constMatrix<T>&x){if(cols!=x.rows)throwDiffer();Matrix<T>temp(rows,x.cols);for(inti=0;i<rows;i++)for(intj=0;j<x.cols;j++){temp(i,j)=0;for(intk=0;k<x.rows;k++)temp(i,j)+=mem[i*cols+k]*x.mem[k*x.cols+j];}returntemp;}//重載求負-template<classT>Matrix<T>Matrix<T>::operator-(){Matrix<T>temp(*this);for(inti=0;i<rows*cols;i++)temp.mem[i]=(-1)*mem[i];returntemp;}/**************************主函數開始***************************/voidmain(){try{//矩陣的行和列必須在1和MAX_SIZE之間Matrix<int>m0(0,3);}catch(...){cout<<"執行語句Matrix<int>m0(0,3);導致矩陣的大小錯誤!
";}try{//矩陣的行和列必須在1和MAX_SIZE之間Matrix<int>max(MAX_SIZE+1,3);}catch(...){cout<<"執行語句Matrix<int>max("<<MAX_SIZE+1<<",3);導致矩陣的大小錯誤!
";}cout<<endl;//定義3行3列的空矩陣m1Matrix<int>m1(3,3);cout<<"InputMatrixm1(3,3):
";//利用已重載的輸入運算符>>輸入矩陣cin>>m1;//利用已重載的輸出運算符<<輸出矩陣cout<<"Matrixm1(3,3):
"<<m1;//利用拷貝構造函數構造矩陣m2(3行3列)Matrix<int>m2(m1);cout<<"Matrixm2(m1):
"<<m2;inta[]={9,8,7,6,5,4,3,2,1};/******************************************************************定義3行3列的空矩陣m3,並用數組a進行初始化****等價於下述語句:****Matrix<int>m3(3,3,a,sizeof(a)/sizeof(int));****構造函數的最後一個參數為數組的長度,默認值為0****當數組長度參數非0時將進行數組長度和矩陣元素個數的匹配檢查!******************************************************************/Matrix<int>m3(3,3,a);cout<<"Matrix<int>m3(3,3,a):
"<<m3;m3=-m1;//求負(矩陣所有元素取相反值)cout<<"Matrixm3=-m1:
"<<m3;m3=m1=m1;//與C++一樣允許連續賦值!cout<<"Matrixm3=m1=m1:
"<<m3;cout<<endl;cout<<"按任意鍵繼續......
";getch();cout<<endl;//矩陣轉置,等價於:m2=m1.transpose();m2=!m1;cout<<"Matrixm2=!m1:
"<<m2;m2.setMatrix(a);//用數組a修改矩陣m2各元素的值cout<<"Matrixm2.setMatrix(a):
"<<m2;m2=m1+m1;//矩陣加cout<<"Matrixm2=m1+m1:
"<<m2;m3=m1*m2;//矩陣乘cout<<"Matrixm3=m1*m2:
"<<m3;m3=m3-m2;//矩陣減cout<<"Matrixm3=m3-m2:
"<<m3;cout<<endl;cout<<"按任意鍵繼續......
";getch();cout<<endl;Matrix<int>m4(4,5),m5(5,4);//利用已重載的運算符()直接給矩陣m4賦值for(inti=0;i<m4.setrows();++i)for(intj=0;j<m4.setcols();++j)m4(i,j)=(i+1)*(j+1);cout<<"Matrixm4:
"<<m4;try{//m4矩陣空間大於存放矩陣m3所有元素的空間m4=m3;cout<<"Matrixm4=m3:
"<<m4;//允許元素個數不相同的矩陣進行賦值!//只要求目標矩陣的容量足夠存放源矩陣的所有元素就允許賦值!}catch(...){cout<<"
執行語句m4=m3;導致矩陣的大小錯誤異常!

";//不允許元素個數不相同的矩陣進行賦值時輸出該信息!}intb[]={0,1,2,3,4,5,6,7,8,9,9,8,7,6,5,4,3,2,1,0};//用數組b修改矩陣m4各元素的值,同時進行個數匹配檢查m4.setMatrix(b,sizeof(b)/sizeof(int));cout<<"m4.setMatrix(b,"<<sizeof(b)/sizeof(int)<<"):
"<<m4;//重載運算符!實現矩陣轉置,與成員函數transpose()功能一致!m5=!m4;cout<<"Matrixm5=!m4:
"<<m5;cout<<endl;cout<<"按任意鍵繼續......
";getch();cout<<endl;cout<<"Matrixm5*m4:
"<<m5*m4;//矩陣乘cout<<"Matrixm4*m5:
"<<m4*m5;//矩陣乘cout<<endl;try{//第1個矩陣的列數不等於第2個矩陣的行數cout<<m4*m4;}catch(...){cout<<"執行語句cout<<m4*m4;導致矩陣的大小(不匹配)錯誤異常!
";}try{//超過矩陣m4的最大行、列數for(i=0;i<=m4.setrows();++i)for(intj=0;j<=m4.setcols();++j)m4(i,j)=(i+1)*(j+1);}catch(...){cout<<"執行上述程序段將導致下標(訪問)越界異常!

";}try{//數組長度不足於給矩陣m4的所有元素賦值m4.setMatrix(a,sizeof(a)/sizeof(int));}catch(...){cout<<"執行語句m4.setMatrix(a,"<<sizeof(a)/sizeof(int)<<");導致數組長度不足異常!
";}try{//雖然數組b有足夠的元素,但指定的長度小於矩陣m4的元素個數m4.setMatrix(b,15);}catch(...){cout<<"執行語句m4.setMatrix(b,15);導致數組長度不足異常!
";}try{//m3矩陣不足於存放矩陣m4的所有元素m3=m4;}catch(...){cout<<"執行語句m3=m4;導致矩陣的大小錯誤異常!
";}try{//第1個矩陣的列數必須等於第2個矩陣的行數才能相乘m3=m1*m4;}catch(...){cout<<"執行語句m3=m1*m4;導致矩陣的大小錯誤異常!
";}try{//兩個矩陣的行數和列數必須完全一致才能相加m3=m4+m1;}catch(...){cout<<"執行語句m3=m4+m1;導致矩陣的大小錯誤異常!
";}try{//兩個矩陣的行數和列數必須完全一致才能相減m3=m4-m1;}catch(...){cout<<"執行語句m3=m4-m1;導致矩陣的大小錯誤異常!
";}cout<<endl;}
推薦閱讀:

隔代教育書(五):第三章 「愛」不是「礙」:如何實現三代同贏(2)
推進依法治國 實現民族復興(1)
中石油:推進戰略採購 實現互利共贏
【珍貴視頻】太極拳脫肩秘法,如何實現「肩打一陰反一陽」?
基本法的初心是什麼?他說要實現港人「心的回歸」

TAG:矩陣 | 模板 | 實現 |