我正在尝试为矩阵类创建构造函数,析构函数和复制构造函数,我不确定我是否做得很好。
特别是,我不确定两件事:
析构函数是否也为复制构造函数中分配的内存释放内存?
关于第Mat[i][j]=other[i][j]
行(请参阅下面的代码),我想知道是否应该写Mat[i][j]=other.Mat[i][j]
代替?
class Matrix
{
private:
int rows;
int cols;
int **Mat;
public:
Matrix (const int &rows,const int &cols);
Matrix (const Matrix &other);
~Matrix ();
};
Matrix::Matrix(const int &n_rows,const int &n_cols) //constructor of class Matrix
{
rows=n_rows;
cols=n_cols;
Mat=new int* [cols];
for(int i =0;i<rows;i++)
Mat[i]=new int[cols];
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
Mat[i][j]=0;
}
Matrix::~Matrix () //destructor
{
for(int i =0;i<rows;i++)
delete Mat[i];
delete[] Mat;
}
Matrix::Matrix(const Matrix &other) //copy constructor
{
cols=other.cols;
rows=other.rows;
Mat=new int* [other.rows];
for(int i =0;i<other.rows;i++)
Mat[i]=new int[other.cols];
for(int i=0;i<other.rows;i++)
for(int j=0;j<other.cols;j++)
Mat[i][j]=other[i][j];
}
答案 0 :(得分:0)
构造函数是一个初始化特定类的对象实例的类操作。
对象创建涉及多个操作,例如:
复制构造函数是构造函数的一个特例,它将同一个类的实例作为输入参数。 - 它仍然是一个构造函数,执行上面提到的相同操作。
析构函数是一个类操作,它负责在不再使用对象时完成对象的最终化。
可以使用它定义的任何构造函数(普通构造函数或复制构造函数)构造对象。删除该对象时,应该在析构函数中释放由类分配的任何内存。
希望这有帮助。
至于你的代码相关问题;在调用复制构造函数时,您传递该类的现有对象实例。由于您没有实现任何运算符重载,因此您可以像访问#2中那样访问对象的属性。
我不确定这是否完全回答了你的问题,但我希望它有所帮助。
答案 1 :(得分:0)
1)我认为解构器只删除属于的对象,因为复制构造的对象有自己的析构函数。
2)是的,Mat[i][j] = other.Mat[i][j]
是正确的,但是如果你想让你的程序更快一点,那就尝试使用指针(我知道这不容易,但是当你习惯了它时那很难^^)
答案 2 :(得分:0)
是。对象仍然分配的任何内容都应该在析构函数中释放。分配给它的构造函数并不重要。
是的,您需要使用Mat[i][j]=other.Mat[i][j]
,特别是因为您尚未为您的班级定义任何operator[]
。
您还需要根据"Rule of Three"添加一个复制赋值运算符,它基本上表示:
如果一个类需要用户定义的析构函数,用户定义的复制构造函数或用户定义的复制赋值运算符,那么它几乎肯定需要全部三个。
试试这个:
class Matrix
{
private:
int rows;
int cols;
int **Mat;
public:
Matrix (int n_rows, int n_cols);
Matrix (const Matrix &other);
~Matrix ();
Matrix& operator=(const Matrix &rhs);
// alternatively:
// Matrix& operator=(Matrix rhs);
};
Matrix::Matrix(int n_rows, int n_cols)
{
rows = n _rows;
cols = n_cols;
Mat = new int*[rows];
for(int i = 0; i < rows; ++i)
{
Mat[i] = new int[cols];
for(int j = 0; i < cols; ++j)
Mat[i][j] = 0;
}
}
Matrix::Matrix(const Matrix &other)
{
rows = other.rows;
cols = other.cols;
Mat = new int*[rows];
for(int i = 0; i < rows; ++i)
{
Mat[i] = new int[cols];
for(int j = 0; j < cols; ++j)
Mat[i][j] = other.Mat[i][j];
}
}
Matrix::~Matrix()
{
for(int i = 0; i < rows; ++i)
delete Mat[i];
delete[] Mat;
}
Matrix& Matrix::operator=(const Matrix &rhs)
{
if (&rhs != this)
{
Matrix temp(rhs);
std::swap(Mat, temp.Mat);
std::swap(rows, temp.rows);
std::swap(cols, temp.cols);
}
return *this;
}
// alternatively:
/*
Matrix& Matrix::operator=(Matrix rhs)
{
std::swap(Mat, rhs.Mat);
std::swap(rows, rhs.rows);
std::swap(cols, rhs.cols);
return *this;
}
*/
更好的解决方案是不要直接使用new[]
/ delete[]
。请改用std::vector
,让它为您处理一切,从而让您的班级遵循&#34;零规则&#34;:
具有自定义析构函数,复制/移动构造函数或复制/移动赋值运算符的类应专门处理所有权(从Single Responsibility Principle开始)。其他类不应该有自定义析构函数,复制/移动构造函数或复制/移动赋值运算符。
class Matrix
{
private:
std::vector<std:vector<int> > Mat;
public:
Matrix (int n_rows, int n_cols);
};
Matrix::Matrix(int n_rows, int n_cols)
{
Mat.resize(n_rows);
for(int i = 0; i < n_rows; ++i)
Mat[i].resize(n_cols, 0);
/* alternatively:
Mat.resize(n_rows, std::vector<int>(n_cols, 0));
*/
}