CPP:矩阵析构函数

问题描述 投票:-3回答:2

对于下面的mymatrix类定义,为什么我不需要析构函数的注释部分?我们是否也不需要删除指针指向的内容?还是因为我们删除了所有不需要的析构函数的有意义的数据?

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;
        }
    }
  }
c++ destructor
2个回答
-1
投票

您需要使用数组删除语法,因为要删除数组,而不是单个对象:

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;
}

-2
投票

我每次看到new/delete中的C++的用法时都在告诉这个。

请不要在new/delete中使用C++

这里是如何创建一个矩阵的最小示例,该矩阵无需任何手动内存分配即可分配和删除自身。

#include <vector>

class Matrix : public std::vector<std::vector<int>> {
public:
  Matrix(size_t numRows, size_t numCols)
      : std::vector<std::vector<int>>(numRows, std::vector<int>(numCols, 0)) {}
  size_t numRows() const { return size(); }
  size_t numCols() const { return front().size(); }
};

int main() {
  auto m = Matrix(5, 4);
  return m[4][3];
}
© www.soinside.com 2019 - 2024. All rights reserved.