这是我第一次使用stackoverflow,很高兴认识你们。 我正在编写一个重载赋值,加法,减法等的矩阵类。 赋值运算符“=”重载部分似乎工作正常,但如果我尝试重载添加“+”运算符,我会收到如下错误消息:
“调试断言失败! 程序:... NTS \ C ++ \ week6 .... \ week6matrix.exe
文件:f:\ dd \ vctools \ crt_bld \ self_x86 \ crt \ src \ dbgdel.cpp
行:52
表达式:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)“
但是如果我在析构函数中删除“delete [] matrix”,一切似乎都有效,但由于这个项目的要求,我需要在析构函数中使用这个术语。
我会张贴一张照片,但这是我第一次使用这个网站,所以我没有这样做的声誉,所以我道歉,如果我的问题似乎没有意义,但我会尝试我的如果您对我的问题有任何进一步的问题,最好解释一下。
谢谢。
#include<iostream>
#include <stdlib.h>
using namespace std;
//dynamic matrix
class dymatrix
{
friend ostream & operator << (ostream &os, dymatrix &om);
friend istream & operator >> (istream &is, dymatrix &om);
private:
int rows;
int columns;
double *matrix;
public:
dymatrix(){cout<<"Default constructor called"<<endl; columns = 0; rows=0; matrix=0;}
dymatrix(int inrows, int incolumns)
{
rows = inrows;
columns = incolumns;
matrix = new double [inrows*incolumns];
for (int i=0; i<inrows*incolumns; i++)
{
matrix[i]=0;
}
}
int lengthr() const {return rows;} //Returns number of rows.
int lengthc() const {return columns;} //Return number of columns.
dymatrix& operator=(dymatrix&);
~dymatrix(){cout<<"Destructor called"<<endl;delete[] matrix;}
int index(int i, int j) //This member function returns the position of each index.
{
if (j > 0 && j <=rows && i > 0 && i <=columns)
{
return (i-1)+(j-1)*columns;
}
else {cout<<"Error, out of range"<<endl; exit (1);}
}
double & operator()(int i, int j) {return matrix[index(i,j)];} //The operator () returns the position of j and i in 1D array.
dymatrix operator + (dymatrix &arr) //overloading addition.
{
if (rows !=arr.rows && columns != arr.columns)
{
cerr<<"SIZE DO NOT MATCH, YOU FAIL"<<endl; exit(1);
}
dymatrix new_matrix(rows,columns);
for (int j = 0; j < arr.rows*arr.columns; j++)
{
//for (int i = 1; i <= arr.columns; i++)
//{
//cout<<"****"<<j<<endl;
new_matrix.matrix[j]= matrix[j]+arr.matrix[j]; //Putting in the data into this dynamic array for each element.
//}
}
return new_matrix;
}
}; //Class end.
dymatrix & dymatrix::operator = (dymatrix &arr) //Overloading "=" operator.
{
if (&arr == this) return *this; //If the array is the same, no need to change, just to print. The key word "this" is a pointer to the object, and *this gives the object.
delete[] matrix; matrix =0; rows =0; columns =0;
rows = arr.rows; //Setting row length.
columns = arr.columns; //Setting column length.
if(rows*columns > 0)
{
matrix = new double [rows*columns]; //Defining a dynamic array here.
for (int j = 1; j <= rows; j++) //Assigning each term to each term.
{
for (int i =1; i <=columns;i++ )
{
matrix[index(i,j)] = arr(i,j); //This is the assigning part, the loop above loops everything so that each term is assigned.
}
}
}
return *this; //Return
}
istream & operator >> (istream &is, dymatrix &om) //Overloading ">>" operator here to
{
cout<<"Please enter the number of rows you want"<<endl;
is >> om.rows; //Inputting number of rows.
cout<<"Enter the number of columns you want"<<endl;
is >> om.columns; //Inputting number of columns.
cout<<"Enter matrix"<<endl;
om.matrix = new double [om.rows*om.columns]; //Making a dynamic array here to put the data in.
for (int j = 1; j <= om.rows; j++)
{
for (int i = 1; i <= om.columns; i++)
{
is >> om.matrix[om.index(i,j)]; //Putting in the data into this dynamic array for each element.
}
}
return is;
}
ostream & operator << (ostream &os, dymatrix &om) //To output the matrix in an standard matrix way
{
for(int j= 1; j<=om.rows; j++)
{
os<<endl<<endl;
for (int i = 1; i <=om.columns;i++)
{
os << om.matrix[om.index(i,j)]<<"\t"; //Similar method used in istream.
}
}
return os;
}
int main()
{
dymatrix a1;
cin >> a1; //Define the rows of the matrix
cout << a1<<endl<<endl;
dymatrix a2;
cin >> a2;
cout << a2<<endl<<endl;
dymatrix resu_a1;
resu_a1=a1+a2;
cout<<"Addition = "<<resu_a1<<endl;
dymatrix resu_a3;
resu_a3 = a1;
cout<<"Assigning = "<<resu_a3<<endl;
return 0;
}
这是我的析构函数:
~dymatrix(){cout<<"Destructor called"<<endl;delete[] matrix;}
这是我重载赋值“=”运算符(在类之外),这似乎有效:
dymatrix & dymatrix::operator = (dymatrix &arr) //Overloading "=" operator.
{
if (&arr == this) return *this; //If the array is the same, no need to change, just to print. The key word "this" is a pointer to the object, and *this gives the object.
delete[] matrix; matrix =0; rows =0; columns =0;
rows = arr.rows; //Setting row length.
columns = arr.columns; //Setting column length.
if(rows*columns > 0)
{
matrix = new double [rows*columns]; //Defining a dynamic array here.
for (int j = 1; j <= rows; j++) //Assigning each term to each term.
{
for (int i =1; i <=columns;i++ )
{
matrix[index(i,j)] = arr(i,j); //This is the assigning part, the loop above loops everything so that each term is assigned.
}
}
}
return *this; //Return
}
但是当我在类中重载加法运算符“+”时,我得到了上面引用的错误。
dymatrix operator + (dymatrix &arr) //overloading addition.
{
if (rows !=arr.rows && columns != arr.columns)
{
cerr<<"SIZE DO NOT MATCH, YOU FAIL"<<endl; exit(1);
}
dymatrix new_matrix(rows,columns);
for (int j = 0; j < arr.rows*arr.columns; j++)
{
//for (int i = 1; i <= arr.columns; i++)
//{
//cout<<"****"<<j<<endl;
new_matrix.matrix[j]= matrix[j]+arr.matrix[j]; //Putting in the data into this dynamic array for each element.
//}
}
return new_matrix;
}
这是我的主要内容:
int main()
{
dymatrix a1;
cin >> a1; //Define the rows of the matrix
cout << a1<<endl<<endl;
dymatrix a2;
cin >> a2;
cout << a2<<endl<<endl;
dymatrix resu_a1;
resu_a1=a1+a2;
cout<<"Addition = "<<resu_a1<<endl;
dymatrix resu_a3;
resu_a3 = a1;
cout<<"Assigning = "<<resu_a3<<endl;
return 0;
}
答案 0 :(得分:0)
当您致电operator +
时,您将返回矩阵的副本,但您的dymatrix
缺少用户定义的副本构造函数:
dymatrix(const dymatrix&); // this is the missing function
您必须实现此功能才能使dymatrix
的返回值正确无误。如果没有此函数,您的代码将显示未定义的行为,并且在对象销毁(双删除错误和/或内存泄漏)时很可能会崩溃。
查看&#34;规则3&#34;。如果实现用户定义的赋值运算符,则还应实现用户定义的复制构造函数和析构函数:
最简单的方法是将大部分(如果不是全部)代码从operator=
移动到复制构造函数。然后使用operator=
惯用法在复制构造函数方面实现copy/swap
:
What is the copy-and-swap idiom?
关于operator=
的实现:为什么要将所有工作从一个数组复制到另一个数组?它应该是一个直线循环,从0到rows*columns
。您不应该调用所有这些无关的函数来获取index
等等。
但是回到复制构造函数,它很可能看起来像这样:
#include <algorithm>
//...
dymatrix::dymatrix(const dymatrix& arr) :
rows(arr.rows), columns(arr.columns),
matrix(new double[arr.rows * arr.columns])
{
std::copy(arr.matrix, arr.matrix + rows*columns, matrix);
}
现在您的赋值运算符可以这样编码:
#include <algorithm>
//...
class dymatrix {
//...
dymatrix& operator=(dymatrix arr); // use this version of assignment operator
//...
};
//...
dymatrix& dymatrix::operator=(dymatrix arr)
{
std::swap(rows, arr.rows);
std::swap(columns, arr.columns);
std::swap(matrix, arr.matrix);
return *this;
}
另一点是,在实施operator+=
之前,您应该已经实施了operator +
。原因是您可以用operator +
来编写operator +=
,从而创建两个运算符,其中operator +
基本上是一个3行函数(当前operator +
中的代码将移至operator +=
。
另一点是,您的operator+
应该传递const dymatrix&
,而不是dymatrix&
。您没有更改函数中的参数,因此应将其作为const
引用传递。
最后一点是,如果添加它们时矩阵的大小不同,那么代码应该抛出异常 - 它应该永远不会只是像代码一样退出程序,并且特别是不在课堂上。
这应该可以解释为什么你不应该这样做(我知道这可能是学校练习,但这样做很糟糕):
exit() call inside a function which should return a reference