矩阵类编写构造函数,解构器和复制构造函数的方式
the way of writing constructor, deconstructor and copy constructor for matrix class
我正在尝试为矩阵类创建一个构造函数,破坏者和复制构造函数,我不确定我是否做得很好。
特别是我不确定两件事:
-
destructor是否应该为复制构造者中分配的内存免费内存?
-
关于行
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];
}
1)我认为解构器仅擦除仅属于的对象,因为复制构造的对象具有自己的驱动器。
2)是的,Mat[i][j] = other.Mat[i][j]
是正确的,但是如果您希望您的程序更快一点,请尝试使用指针(我知道这不是很容易^^)
a 构造函数是一个类操作,可以初始化特定类的对象实例。
对象创建涉及多个操作,例如:
- 分配内存以存储新对象的结构
- 正确初始化对象的属性。
a 复制构造函数是构造函数的一种特殊情况,它的实例与输入参数相同。 - 它仍然是一个构造函数,执行上述相同的操作。
a destructor 是一个类操作,当对象不再使用时,负责最终确定对象。
可以使用其定义的任何构造函数,即普通构造函数或复制构造函数来构造一个对象。当您删除该对象时,应在破坏者中对类分配的任何内存进行交易。
希望这会有所帮助。
至于与代码相关的问题;调用复制构造函数时,您将通过类的现有对象实例。由于您没有实施任何操作员过载,因此您可以访问对象的属性,如#2中所说的。
。我不确定这是否完全回答您的问题,但我希望它会有所帮助。
-
是。物体仍然分配的任何东西都应释放在灾难中。分配了哪个构造函数都没关系。
-
是的,您需要使用
Mat[i][j]=other.Mat[i][j]
,尤其是因为您尚未为课程定义任何operator[]
。
您还需要根据"三个规则"添加复制分配运算符,该操作员基本上指出:
类需要用户定义的驱动器,用户定义的复制构造函数或用户定义的复制分配运算符,它几乎可以肯定需要所有三个。
尝试以下操作:
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
,让它为您处理所有内容,从而允许您的课程遵循"零规则":
具有自定义驱动器,复制/移动构造函数或复制/移动分配操作员的类应专门处理所有权(根据单个责任原则遵循)。其他类不应具有自定义驱动器,复制/移动构造函数或复制/移动分配操作员。
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));
*/
}
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 使用复制构造函数复制双精度数组
- C 无可行的构造函数复制类型的变量
- 没有可行的构造函数复制类型 'MyString' 的数组元素
- 编译时,复制构造函数/复制分配和正常功能调用优化之间是否存在任何区别
- 如何最小化调用列表构造函数(复制构造函数)的次数?
- C 11矢量构造函数复制与范围
- 我定义了一个非复制构造函数;复制构造函数还会被隐式定义吗
- 可以将构造函数复制为转换运算符
- 将基类指针的构造函数复制到子类
- C++树类:构造函数/复制/内存泄漏
- 如何制作这个在模板构造函数复制中使用类型定义的类型的模板
- 将构造函数复制为模板化的成员函数
- 绕过私有复制构造函数/复制赋值C++
- C++通过构造函数复制对象
- 复制构造函数 - 复制C++中的对象
- 将带unique_ptr的类的构造函数复制到作为成员的抽象类