模板中的通用析构函数<类 T>当 t = int * 或 t = int 时

universal destructor in template <class T> when t = int * or t = int

本文关键字:int gt 析构函数 lt      更新时间:2023-10-16

几天前我写了一个模板类,看起来像这样:

template <class T>
class Matrix {
private:
    T ** matrix;
    int n;
    int m;
      .
      .
      .
}

和构造函数:

template <class T>
Matrix<T>::Matrix(int _n, int _m)
{
      n = _n;
      m = _m;
      matrix = new  T * [n];
        for (int i = 0; i < n; i ++)
        {
            matrix[i] = new T[m];
        }
}

现在我想创建一个析构函数,像这样:

template <class T>
aghMatrix<T>::~aghMatrix()
{
    for (int i = 0; i < n; i ++)
    {
        delete [] matrix[i];
    } 
    }

起初我以为它能解决所有问题,但我错了。函数main:

Matrix<int> a; //destructor works find
Matrix<int*>a; //error destructor

如何解决这个问题?

我假设这是某种编码练习。对于实际应用程序,您不应该编写自己的矩阵实现,而应该依赖于标准库中的容器或许多矩阵库中的一个。

发布的示例有几个问题,甚至无法编译。我先给出一个最小解:

template <class T>
class Matrix {
public:
    Matrix(int _n, int _m)
        : n(_n), m(_m), matrix(new T*[n])  // always initialize your members
    {
        for (int i=0; i<n; i++)
        {
            matrix[i] = new T[m];
        }
    }
    ~Matrix()
    {
        for (int i=0; i<n; i++)
        {
            delete[] matrix[i];
        }
        delete[] matrix; // this deletes the first level
    }
private:
    int n;
    int m;
    T ** matrix;
};

我们应该从中学到的是:

  • 确保初始化了构造函数中的每个类成员

  • 不要忘记删除你的第一级指针指向的内存(析构函数的最后一行)

  • 如果你不需要

  • ,不要使用明确的newdelete
  • 关于复制和移动语义呢?

为了使用RAII并避免显式的delete,您可以使用std::unique_ptr来代替。等效代码现在看起来像这样:

#include <memory>
template <class T>
class Matrix2 {
public:
    Matrix2(int _n, int _m)
        : n(_n), m(_m), matrix(new T[n * m])
    {}
private:
    int n;
    int m;
    std::unique_ptr<T> matrix;
};

更简单,更不容易出错。唯一指针现在负责资源管理。注意,我分配了T类型的n * m对象,这意味着您的矩阵访问操作符将看起来像这样:

    T operator()(int i, int j)
    {
        return matrix.get()[i * n + j];
    }

unique_ptr可以移动,但不能复制,这意味着你现在可以安全地移动Matrix2,但不能复制。复制语义必须显式定义:

    Matrix2(const Matrix2& other)
        : n(other.n),  m(other.m), matrix(new T[n * m])
    {
        std::copy(other.matrix.get(), other.matrix.get() + n * m, matrix.get());
    }
    Matrix2& operator=(const Matrix2& other)
    {
        if (this != &other)
        {
            n = other.n;
            m = other.m;
            matrix.reset(new T[n * m]);
            std::copy(other.matrix.get(), other.matrix.get() + n * m, matrix.get());
        }
        return *this;
    }

请注意,这段代码仅用于演示目的,仍然缺乏重要的方面,不应该在实际应用程序中使用。