题目要求:编写一个矩阵类,通过成员函数重载运算符实现矩阵的加法,数乘,乘法。
大家不用看具体的代码实现,主要关注的是重载运算符和析构函数部分,这是我想表达的重点。
代码1:
#include <iostream>
using namespace std;
static int counts = 0;
class Matrix {
private:
int row;
int column;
int *matrix;
public:
Matrix(){
row = 0;
column = 0;
matrix = NULL;
};
Matrix(int m[2][2]){
int i,j;
row = 2;
column = 2;
matrix = new int[row*column];
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
matrix[i*column+j] = m[i][j];
}
}
};
~Matrix(){
delete []matrix;
cout << "已析构" << ++counts << "个对象" << endl;
};
void print(){
int i,j;
for (i = 0; i < row; i++) {
for (j = 0 ; j < column; j++) {
cout << matrix[i*row+j] << " " ;
}
cout << endl;
}
}
friend Matrix operator+(Matrix m1,Matrix m2){
int m[2][2];
int i,j;
for (i = 0; i < m1.row; i++) {
for (j = 0; j < m1.column; j++) {
m[i][j] = m1.matrix[i*m1.column+j]+m2.matrix[i*m1.column+j];
}
}
return Matrix(m);
}
friend Matrix operator*(Matrix m1,Matrix m2){
int m[2][2]={0,0,0,0};
int i,j,k = 0;
for (i = 0; i < m1.row; i++) {
for(k = 0;k < m2.column;k++){
for (j = 0; j < m1.column; j++) {
m[i][k] += m1.matrix[i*m1.column+j]*m2.matrix[j*m2.column+k];
}
}
}
return Matrix(m);
}
friend Matrix operator*(Matrix m1,int cst){
int m[2][2];
int i,j;
for (i = 0; i < m1.row; i++) {
for (j = 0; j < m1.column; j++) {
m[i][j] = m1.matrix[i*m1.row+j]*cst;
}
}
return Matrix(m);
}
};
int main() {
int v1[2][2] = {1,2,3,4};
int v2[2][2] = {1,2,3,4};
Matrix m1(v1), m2(v2);
m1.print();
m2.print();
Matrix m3 = m1 + m2;
m3.print();
cout << "m3:我要被析构了" << endl;
Matrix m4 = m3 * 10;
cout << "m3:我被析构了" << endl;
m4.print();
Matrix m5 = m1 * m2;
m5.print();
return 0;
}
在没有注释delete []matrix 下,Xcode、Visual Code 、Codeblock和Dev C运行结果图如下:
可以看到,无一例外,每个编译器都报错了(事实上,Visual Code第一次还对了,但后来都是错的)
在注释掉delete []matrix之后,Xcode、Visual Code 、Codeblock和Dev C运行结果图如下:
代码段2:根据代码一稍微修改,没有用friend的方法而已
#include <iostream>
using namespace std;
static int counts = 0;
class Matrix {
private:
int row;
int column;
int *matrix;
public:
Matrix(){
row = 0;
column = 0;
matrix = NULL;
};
Matrix(int m[2][2]){
int i,j;
row = 2;
column = 2;
matrix = new int[row*column];
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
matrix[i*column+j] = m[i][j];
}
}
};
~Matrix(){
delete []matrix;
cout << "已析构" << ++counts << "个对象" << endl;
};
void print(){
int i,j;
for (i = 0; i < row; i++) {
for (j = 0 ; j < column; j++) {
cout << matrix[i*row+j] << " " ;
}
cout << endl;
}
}
Matrix operator+(Matrix m2){
int m[2][2];
int i,j;
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
m[i][j] = matrix[i*column+j]+m2.matrix[i*column+j];
}
}
return Matrix(m);
}
Matrix operator*(Matrix m2){
int m[2][2]={0,0,0,0};
int i,j,k = 0;
for (i = 0; i < row; i++) {
for(k = 0;k < m2.column;k++){
for (j = 0; j < column; j++) {
m[i][k] += matrix[i*column+j]*m2.matrix[j*m2.column+k];
}
}
}
return Matrix(m);
}
Matrix operator*(int cst){
int m[2][2];
int i,j;
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
m[i][j] = matrix[i*row+j]*cst;
}
}
return Matrix(m);
}
};
int main() {
int v1[2][2] = {1,2,3,4};
int v2[2][2] = {1,2,3,4};
Matrix m1(v1), m2(v2);
m1.print();
m2.print();
Matrix m3 = m1 + m2;
m3.print();
cout << "m3:我要被析构了" << endl;
Matrix m4 = m3 * 10;
cout << "m3:我被析构了" << endl;
m4.print();
Matrix m5 = m1 * m2;
m5.print();
return 0;
}
在没有注释delete []matrix 下,Xcode、Visual Code 、Codeblock和Dev C运行结果图如下:
在注释掉delete []matrix之后,Xcode、Visual Code 、Codeblock和Dev C运行结果图如下:
以上可见,在注释delete []matrix之前,四种编译器都报出错误,但也同时在过程中析构了相应对象;在注释delete []matrix之后,只有Visual Code仍然报出错误,但是其他三种编译器都可以显示正确的矩阵运算结果。
那为什么中间过程中会出现析构呢?
现在知道在过程中出现多次析构对象的原因了,仅仅就是值传递的问题,使用引用赋值就不会有问题了,但还是没有解决pointer be freed was not located的问题,难道只能拷贝一次吗,是不是又会关于构造函数的拷贝问题,还是深浅拷贝的问题,有待研究。