C++矩阵类中的运算符重载和二维数组动态申请内存
学校的题
3、矩阵(三)
编写C++程序完成以下功能:
(1)用类来实现矩阵,定义一个矩阵的类,属性包括:
1.矩阵大小,用 lines, rows(行、列来表示);
2.存贮矩阵的数组指针,根据矩阵大小动态申请(new)。
(2)矩阵类的方法包括:
1.构造函数,参数是矩阵大小,需要动态申请存贮矩阵的数组;
2.析构函数,需要释放矩阵的数组指针;
3.拷贝构造函数,需要申请和复制数组;
4.输入,可以从cin中输入矩阵元素;
5.输出,将矩阵格式化输出到cout;
6.矩阵相加的函数,实现两个矩阵相加的功能,结果保存在另一个矩阵类,但必须矩阵大小相同;
7.矩阵相减的函数,实现两个矩阵相减的功能,结果保存在另一个矩阵类,但必须矩阵大小相同。
##二维数组动态申请内存
有三种方法:
1.两层指针,先申请一个指针数组,再为数组中每个指针申请内存
//申请:
int **Matrix = new int*[ROW];
for (int i = 0; i < ROW; i++)
Matrix[i] = new int[COL];
//释放:
for (int i = 0; i < ROW; i++)
delete[] p[i];//先释放指针数组中的一级指针
delete[] p;//在释放二级指针
**优劣:**行和列都可以是变量,但是写起来麻烦。
2.给行指针申请内存
int (*a)[10]表示一个行指针,这个行指针指向10个int的一个数组。
(注:int *a[10]就是定义10个元素的指针数组)
int(*Matrix)[COL] = new int[ROW][COL];//为行指针申请row的内存
//也可以写作int(*A2)[COL] = (int(*)[COL])new int[ROW*COL];
delete[]Matrix;
**优劣:**好写好删除,但是列要是个常数 。
3.定义一级指针,直接申请一片内存
int *Matrix = new int[ROW*COL];
for (int i = 0; i < ROW*COL; i++)
cin >> Matrix[i];
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
cout << Matrix[ROW*i + j] << " ";
cout << "\n";
}
delete Matrix;
**优劣:**行列都可以是变量,也很好写,但是用起来和二维数组不太一样,可能会有点麻烦 。
##运算符重载
本题中要求了=号重载,=号重载的必要在于:
1.当类动态申请内存以后,编译器默认的=函数浅拷贝,也就是不会删除掉原有的内存再申请新内存的。
2.有了拷贝构造函数为什么还要重载=函数?拷贝构造函数是在对象一开始被定义构造的时候使用。对已有对象的赋值用=函数。
运算符重载的要点:
1.传入参数为const & class:如果传入的不是引用会又调用形式参数的构造函数和析构函数,当类很大的时候造成增大开销。
2.返回也是引用:如果返回是一个类,会调用构造函数和析构函数,再次增大开销。
3.在+重载里不用普通的Matrix对象而用动态申请的对象:函数结束时在栈里的局部变量都会被析构,返回回来的是个空的对象,new的东西在堆里面,不会被自动释放,只能手动释放。
代码
#include <iostream>
#include <iomanip>
using namespace std;
class Matrix
{
int lines, rows;
int *M;//矩阵的指针
public:
Matrix(int, int, int *);
Matrix(Matrix&);
//构造函数
void Set(int, int);
friend ostream& operator <<(ostream&, const Matrix&);
friend istream& operator >>(istream&, const Matrix&);
Matrix& operator + (const Matrix&);
Matrix& operator - (const Matrix&);
Matrix& operator = (const Matrix&);
~Matrix();
};
Matrix::Matrix(int line=0, int row=0,int *pM=NULL)//构造函数
{
if (line < 0 || row < 0)//不能传入负数
{
cout << "error matrix!\n";
lines = rows = 0;
return;
}
lines = line;
rows = row;
M = new int[lines*rows];//申请内存
}
Matrix::Matrix(Matrix& M2)//拷贝构造函数
{
lines = M2.lines;
rows = M2.rows;
M = new int[lines*rows];//申请内存
for(int i=0;i<rows*lines;i++)
M[i] = M2.M[i];//赋值
}
void Matrix::Set(int line=-1, int row=-1)
{
if (line != -1)//line不缺省,需要更新lines的值
lines = line;
if (row != -1)//row不缺省,需要更新rows的值
rows = row;
//更新长宽完成
if (line < 0 || row < 0)
{
cout << "error matrix!\n";
lines = rows = 0;
return;
}
if (M != NULL)delete M;//删除原有内存
M = new int[lines*rows];
//重新申请内存
}
istream& operator >>(istream& istr, const Matrix& m)
{
for (int i = 0; i <m.lines*m.rows; i++)
istr >> m.M[i];
return istr;
}
ostream& operator <<(ostream& ostr, const Matrix& m)
{
for (int i = 0; i < m.lines; i++)
{
for (int j = 0; j <m.rows; j++)
ostr << setw(4) << m.M[i*m.lines+j] << " ";
ostr << '\n';
}
ostr << '\n';
return ostr;
}
Matrix& Matrix::operator + (const Matrix& M2)
{
if (M2.lines != lines || M2.rows != rows)//矩阵大小不一样
{
cout << "The two matrixs can't do the operation!\n";
return Matrix();//返回空矩阵
}
Matrix *M3 =new Matrix(lines,rows);
//new的东西是在堆里面,函数结束不会被删除
Matrix& Re =*M3;
for (int i = 0; i < lines * rows; i++)
M3->M[i] = M[i] + M2.M[i];
return Re;//传引用就不会调用构造函数,节省开销
}
Matrix& Matrix::operator - (const Matrix& M2)
{
if (M2.lines != lines || M2.rows != rows)//矩阵大小不一样
{
cout << "The two matrixs can't do the operation!\n";
return Matrix();
}
Matrix *M3 = new Matrix(lines, rows);
//new的东西是在堆里面,函数结束不会被删除
Matrix& Re =*M3;//建立那片内存的引用
for (int i = 0; i < lines*rows; i++)
M3->M[i] = M[i] - M2.M[i];
return Re;//传引用就不会调用构造函数,节省开销
}
Matrix& Matrix::operator=(const Matrix& M2)
{
if (this != &M2)//防止自赋值
{
if(M!=NULL)delete M;
lines = M2.lines;
rows = M2.rows;
M = new int[lines*rows];//重新开辟内存
for (int i = 0; i < lines*rows; i++)
M[i] = M2.M[i];
}
return *this;
}
Matrix::~Matrix()
{
delete M;
}
int main()
{
int line, row;
Matrix A1, A2, A3;
Matrix* pA1 = new Matrix;
Matrix* pA2 = new Matrix;
Matrix* pA3 = new Matrix;
cout << "Input lines and rows of matrixA1:\n";
cin >> line >> row;
A1.Set(line, row);
cout << "Input A1:\n";
cin >> A1;
//输入A1
cout << "Input lines and rows of matrixA2:\n";
cin >> line >> row;
A2.Set(line, row);
cout << "Input A2:\n";
cin >> A2;
//输入A2
cout<< "\n\n";
A3 = A1 + A2;
cout << A1 << "+\n" << A2 << "=\n"<< A3 << "\n\n";
A3 = A1 - A2;
cout << A1 << "-\n" << A2 << "=\n" << A3 << "\n\n";
cout << "\n\n";
cout << "Input lines and rows of matrixpA1:\n";
cin >> line >> row;
pA1->Set(line, row);
cout << "Input pA1:\n";
cin >> *pA1;
//输入pA1
cout << "Input lines and rows of matrixpA2:\n";
cin >> line >> row;
pA2->Set(line, row);
cout << "Input pA2:\n";
cin >> *pA2;
cout << "\n\n";
//输入pA2
*pA3 = *pA1 + *pA2;
cout << *pA1 << "+\n" << *pA2 << "=\n" << *pA3 << "\n\n";
*pA3 = *pA1 - *pA2;
cout << *pA1 << "-\n" << *pA2 << "=\n" << *pA3 << "\n\n";
system("pause");
return 0;
}