关于c++在类中动态建立二维数组及运算符重载的问题

我写的一个代码,有问题实在找不出来,哪位大神帮帮我~
以下是部分代码:
//运算符重载实现矩阵加法
#include<iostream.h>
using namespace std;
class Matrix
{
public:
Matrix(int mm, int nn)
{
m=mm;n=nn;
int i;
data=new double*[mm];//动态建立二维数组
for(i=0;i<mm;i++)
data[i]=new double[nn];
} //构造M行N列的矩阵
~Matrix()//析构函数释放data
{
for(int i=0;i<m;i++)
delete []data[i];//就是这里有问题,烦死我了
delete []data;
}
Matrix operator + (Matrix &m2);//运算符重载实现矩阵加法
void display()
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
cout<<data[i][j]<<" ";
}
cout<<endl;
}
}
void input()
{
cout<<"请输入矩阵的数据:"<<endl;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
cin>>data[i][j];
}
}
private:
double **data;
int m,n;//矩阵的行数,列数
};//类定义结束
Matrix Matrix::operator +(Matrix &m2)
{
Matrix m3(this->m,this->n);
if(this->m!=m2.m||this->n!=m2.n) {cout<<"矩阵不匹配"<<endl; exit(0);}
int i,j;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
m3.data[i][j]=this->data[i][j]+m2.data[i][j];
}
return m3;
}
int main(int argc, char* argv[])
{
int a,b,c,d;
cout<<"请输入第一个矩阵的行数和列数:"<<endl;
cin>>a>>b;
Matrix A(a,b);
A.input();
A.display();
cout<<"请输入第二个矩阵的行数和列数:"<<endl;
cin>>c>>d;
Matrix B(c,d);
B.input();
B.display();
Matrix C(a,b);//可以改为Matrix C,但是还得在类中加不带参的构造函数
C=A+B;
C.display();
return 0;
}
代码运行后没有error,但是数组输入完毕后系统就崩溃了,debug后发现是析构函数delete那部分有问题,可是我就是不会改,麻烦大神们帮我看看。

C++在定义成员中含有指针的类时,是比较复杂的,要考虑深拷贝问题。对于这个程序来说,需要重载拷贝构造函数和=运算符。不然C=A+B;是无法正确执行的。
比如A+B的返回值是return m3;这里的return实际上就需要调用Matrix类的拷贝构造函数,生成一个m3的备份来返回(因为m3是局部变量,无法在离开+函数后还存在)。如果你不自己写个深拷贝的构造函数的话,这个备份仅仅是data指针的值和m3的data相同,指向的也是m3的data所指向的内存空间。而m3释放后,这块内存空间已经被释放了,所以这个备份的data指针就成了野指针,在析构时当然会出现错误。
再比如=如果不重载,C也会是m3的备份,同样会出现因为m3释放后,C的data指针成为野指针的问题。
所以必须实现深拷贝的拷贝构造函数和=运算符重载函数,把m3的data所指向内存空间全部备份一次,这样m3释放时就不会影响到C了。

#include<iostream>
using namespace std;
class Matrix
{
public:
Matrix(int mm, int nn)
{
m=mm;n=nn;
int i;
data=new double*[mm];//动态建立二维数组
for(i=0;i<mm;i++)
data[i]=new double[nn];
} //构造M行N列的矩阵
Matrix(const Matrix &src) //注意,要重载拷贝构造函数
{
m=src.m;n=src.n;
int i,j;
data=new double*[m];//动态建立二维数组
for(i=0;i<m;i++)
data[i]=new double[n];
for(i=0;i<m;i++)
for(j=0;j<n;j++)
data[i][j]=src.data[i][j];
}
~Matrix()//析构函数释放data
{
for(int i=0;i<m;i++)
delete []data[i];//就是这里有问题,烦死我了
delete []data;
}
Matrix& operator=(const Matrix &src) //注意,要重载=运算符
{
int i,j;
for(i=0;i<m;i++)
delete []data[i];
delete []data;

m=src.m;n=src.n;
data=new double*[m];//动态建立二维数组
for(i=0;i<m;i++)
data[i]=new double[n];
for(i=0;i<m;i++)
for(j=0;j<n;j++)
data[i][j]=src.data[i][j];
return *this;
}
Matrix operator + (Matrix &m2);//运算符重载实现矩阵加法
void display()
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
cout<<data[i][j]<<" ";
}
cout<<endl;
}
}
void input()
{
cout<<"请输入矩阵的数据:"<<endl;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
cin>>data[i][j];
}
}
private:
double **data;
int m,n;//矩阵的行数,列数
};//类定义结束
Matrix Matrix::operator +(Matrix &m2)
{
Matrix m3(this->m,this->n);
if(this->m!=m2.m||this->n!=m2.n) {cout<<"矩阵不匹配"<<endl; exit(0);}
int i,j;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
m3.data[i][j]=this->data[i][j]+m2.data[i][j];
}
return m3;
}
int main(int argc, char* argv[])
{
int a,b,c,d;
cout<<"请输入第一个矩阵的行数和列数:"<<endl;
cin>>a>>b;
Matrix A(a,b);
A.input();
A.display();
cout<<"请输入第二个矩阵的行数和列数:"<<endl;
cin>>c>>d;
Matrix B(c,d);
B.input();
B.display();
Matrix C(a,b);//可以改为Matrix C,但是还得在类中加不带参的构造函数
C=A+B;
C.display();
return 0;
}
温馨提示:内容为网友见解,仅供参考
第1个回答  2011-11-29
你看看这个 具体原理和解释明天再说好么 我电脑没电了
#include<iostream>
using namespace std;
class Matrix
{
public:
Matrix(int mm, int nn)
{
m=mm;n=nn;
int i;
data=new double*[mm];//动态建立二维数组
for(i=0;i<mm;i++)
data[i]=new double[nn];
} //构造M行N列的矩阵
Matrix(Matrix &another)
{
m=another.m;n=another.n;
int i,j;
data=new double*[m];//动态建立二维数组
for(i=0;i<m;i++)
data[i]=new double[n];
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
data[i][j]=another.data[i][j];
}
}
~Matrix()//析构函数释放data
{
for(int i=0;i<m;i++)
{
delete []data[i];//问题,烦死我了
}
delete []data;
}
Matrix operator + (Matrix &m2);//运算符重载实现矩阵加法
void display()
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
cout<<data[i][j]<<" ";
}
cout<<endl;
}
}
void input()
{
cout<<"请输入矩阵的数据:"<<endl;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
cin>>data[i][j];
}
}
private:
double **data;
int m,n;//矩阵的行数,列数
};//类定义结束
Matrix Matrix::operator +(Matrix &m2)
{
Matrix m3(this->m,this->n);
if(this->m!=m2.m||this->n!=m2.n) {cout<<"矩阵不匹配"<<endl; exit(0);}
int i,j;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
m3.data[i][j]=this->data[i][j]+m2.data[i][j];
}
return m3;
}
int main(int argc, char* argv[])
{
int a,b,c,d;
cout<<"请输入第一个矩阵的行数和列数:"<<endl;
cin>>a>>b;
Matrix A(a,b);
A.input();
A.display();
cout<<"请输入第二个矩阵的行数和列数:"<<endl;
cin>>c>>d;
Matrix B(c,d);
B.input();
B.display();
// Matrix C(a,b);//可以改为Matrix C,但是还得在类中加不带参的构造函数
Matrix C=A+B;
C.display();
return 0;
}
第2个回答  2011-11-28
for(int i=0;i<m;i++)
delete data[i];// 这样就行了
delete []data;追问

我试了一下,还是不行~~~

追答

二维数组就这么析构,除非你的问题不在这

追问

嗯,我觉得是加法重载的那部分有问题。。真晕啊。麻烦你了

关于c++中重载的问题
函数重载是指对现有的函数进行重载,重载函数与被重载的函数的函数名相同,但参数类型、参数个数和返回类型中有一个或者多个不同,以示区别 运算符重载是指对C++中部分运算符赋予其它功能

【C++】常见二义性问题(更新中)
掌握这些常见二义性问题,你将更好地驾驭C++的复杂性,让代码更加清晰和可靠。在实践中不断学习和改进,你的编程之旅将更为顺畅。

c++关于运算符重载的问题
2 char &charArray::operator[](int i)\/\/&是什么用,去掉会出错 返回的是一个char 型的变量,去掉的话返回的是char型的值。前者可以作为变量对它进行赋值。后者只是一个char型的值而已

求助,关于一道C++函数重载的问题
1、运算符重载不改变操作符原先的优先级、结合性和操作数数目,++是单目操作符,所以1不会成立的。你有这样的问题大概是因为双目操作符比如*,可以有x.operator*(y)这种写法吧? 但是这个不改变*是二目操作符的事实。C++规定:双目操作符重载作为成员函数时只能有一个形参,调用方为左操作数,形参...

关于C++重载运算符
① 赋值运算符(=)可以用于每一个类对象,可以利用它在同类对象之间相互赋值。② 地址运算符&也不必重载,它能返回类对象在内存中的起始地址。总之,当C++语言原有的一个运算符被重载之后,它原先所具有的语义并没有消失,只相当于针对一个特定的类定义了一个新的运算符。运算符重载可以使用成员函数和...

C++关于运算符重载的一道题
选C.看题目:-- 若在表达式“y\/x”(y在前面),"\/"是作为成员函数重载(成员函数)的运算符 调用y的成员函数operator\/, 也就是 y.operator\/(x)

请教关于C++中重载的问题1
指针P声明为公有的才能访问,就按友好函数访问的权限解释,因为你在重载函数中用到了Strcmp库函数,而它并不是类String的友好函数,因此是不能访问到指针P的 include <iostream> include<string> using namespace std;class String { public:String(){p=NULL;} String(char *str);friend bool ...

关于c++中运算符重载的题 谢谢 有一个double的数和一个复数相加 分两种...
friend Complex operator +(Complex &c1,Complex &c2);\/\/运算符重载 private:double real;double imag;};Complex operator +(Complex &c1,Complex &c2){ Complex temp;temp.real=c1.real +c2.real;temp.imag=c1.imag +c2.imag;return temp;} void Complex::write (){ cout<<"请输入实部...

一个关于C++重载的问题
assistant operator [](int i)\/\/重载下标运算符 { assistant assis;assis.aPtr=ptr;assis.n=size2;assis.i=i;return assis;} Array2 & operator = (Array2 & s){ if(ptr) delete [] ptr;ptr = new int[size1 * size2];for(int i = 0; i < size1; i ++){ for(int j = 0...

C++重载运算符。 太TM难了。 进来看看
是正确的,因为函数f()是类A的成员。注:cout和cin都是C++中iostream类的一个对象,对于cout<<使用的<<运算符,是在类中被重载了的,因此<<运算符就是一个重载的操作运算符。将操作符重载函数声明为友元时,这时的操作符重载函数必须多一个形参,若操作符成员函数是类的成员函数,则要少一个形参...

相似回答