【问题标题】:universal destructor in template <class T> when t = int * or t = int当 t = int * 或 t = int 时,模板 <class T> 中的通用析构函数
【发布时间】:2015-08-21 12:20:37
【问题描述】:

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

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

如何解决这个问题?

【问题讨论】:

  • 由于多种原因,您发布的代码甚至无法编译。请张贴SSCCE,然后复制粘贴您看到的确切错误消息,error destructor 没有意义。
  • 您没有显示您的示例 实际上 调用的默认构造函数的代码。您展示了您的示例调用的构造函数的代码(除非您的参数具有默认值,但您没有展示)。
  • 顺便说一句,delete[] matrix; 不见了...简化您的生活并使用std::vector

标签: c++ templates destructor


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 2014-09-15
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    相关资源
    最近更新 更多