模板中的通用析构函数<class t =“”>当t = int *或t = int

时间:2015-06-06 16:56:02

标签: c++ templates destructor

前几天我写了一个模板类,如下所示:

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

如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

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

发布的示例有几个问题,甚至无法编译。所以,让我首先提供一个最小的解决方案:

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代替{{3}}。等效代码现在看起来像这样:

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

更简单,更不容易出错。唯一指针现在正在处理资源管理。请注意,我分配n * m类型的T对象,这意味着您的矩阵访问运算符将如下所示:

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

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