对于下面的mymatrix
类定义,为什么我不需要析构函数的注释部分?我们不需要删除 a 指针指向的内容吗?还是因为我们删除了所有不需要析构函数的这些(注释掉的)部分的有意义的数据?
template<typename T>
class mymatrix
{
private:
struct ROW
{
T* Cols; // dynamic array of column elements
int NumCols; // total # of columns (0..NumCols-1)
};
ROW* Rows; // dynamic array of ROWs
int NumRows; // total # of rows (0..NumRows-1)
}
析构函数:
virtual ~mymatrix()
{
for(int r=0;r<numRows;r++)
{
for(int c=0;c<Rows[r].NumCols;c++)
{
delete Rows[r].Cols[c];
}
// delete Rows[r];
}
// delete Rows;
}
构造函数:
mymatrix(int R, int C)
{
if (R < 1)
throw invalid_argument("mymatrix::constructor: # of rows");
if (C < 1)
throw invalid_argument("mymatrix::constructor: # of cols");
Rows = new ROW[R]; // an array with R ROW structs:
NumRows = R;
//intialize each row to C columns
for(int r=0;r<R;r++){
Rows[r].Cols=new T[C];
Rows[r].NumCols=C;
//initialize elements to their default value
for(int c=0;c<Rows[r].NumCols;c++){
Rows[r].Cols[c]=T{}; // default value for type T;
}
}
}
您需要使用数组删除语法,因为您要删除的是数组,而不是单个对象:
delete[] Rows[r].Cols
...
delete[] Rows
编辑:我最初只是简单地包含了正确的delete[]
运算符用法,并在我的原始示例中为简洁起见保留了所有内容,但正如@idclev463035818 指出的那样,每当您定义自己的析构函数、复制构造函数或复制赋值运算符(尤其是当它们涉及动态内存分配时) ),您几乎总是需要拥有所有三个。几乎从不想要任何一个没有其他对象,因为如果您的对象中有原始指针,那么它们将被浅复制到正在实例化的新对象。然后,这些对象中的每一个的析构函数将被调用并多次尝试删除相同的内存部分,这是一个重大错误。我已将这些添加到代码示例中,并在main
函数的新测试中使用它们。
完整代码:
#include <iostream>
using namespace std;
template<typename T>
class mymatrix
{
public:
struct ROW
{
T* Cols; // dynamic array of column elements
int NumCols; // total # of columns (0..NumCols-1)
};
ROW* Rows; // dynamic array of ROWs
int NumRows; // total # of rows (0..NumRows-1)
public:
mymatrix(int R, int C)
{
init(R, C);
}
void init(int R, int C) {
if (R < 1)
throw "";//throw invalid_argument("mymatrix::constructor: # of rows");
if (C < 1)
throw "";//invalid_argument("mymatrix::constructor: # of cols");
Rows = new ROW[R]; // an array with R ROW structs:
NumRows = R;
//intialize each row to C columns
for (int r = 0; r < R; r++) {
Rows[r].Cols = new T[C];
Rows[r].NumCols = C;
//initialize elements to their default value
for (int c = 0; c < Rows[r].NumCols; c++) {
Rows[r].Cols[c] = T{}; // default value for type T;
}
}
}
mymatrix(const mymatrix& other) : mymatrix(other.NumRows, other.Rows[0].NumCols) {
for (int r = 0; r < NumRows; ++r) {
ROW& thisRow = Rows[r];
ROW& otherRow = other.Rows[r];
for (int c = 0; c < thisRow.NumCols; ++c) {
thisRow.Cols[c] = otherRow.Cols[c];
}
}
}
mymatrix& operator=(const mymatrix& other) {
if (other.NumRows != NumRows || other.Rows[0].NumCols != Rows[0].NumCols) {
clear();
init(other.NumRows, other.Rows[0].NumCols);
}
for (int r = 0; r < NumRows; ++r) {
ROW& thisRow = Rows[r];
ROW& otherRow = other.Rows[r];
for (int c = 0; c < thisRow.NumCols; ++c) {
thisRow.Cols[c] = otherRow.Cols[c];
}
}
return *this;
}
void clear() {
for (int r = 0; r < NumRows; r++)
{
delete[] Rows[r].Cols;
}
delete[] Rows;
Rows = NULL;
NumRows = 0;
}
virtual ~mymatrix()
{
clear();
}
};
int main() {
mymatrix<int> mat(5, 5);
mat.Rows[0].Cols[2] = 5;
mymatrix<int> matClone(mat);
cout << matClone.Rows[0].Cols[2] << endl;
matClone.Rows[0].Cols[1] = 8;
cout << mat.Rows[0].Cols[1] << endl;
mat = matClone;
cout << mat.Rows[0].Cols[1] << endl;
system("pause");
return 0;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句