模板中的通用析构函数<类 T>当 t = int * 或 t = int 时
universal destructor in template <class T> when t = int * or t = int
几天前我写了一个模板类,看起来像这样:
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;
};
我们应该从中学到的是:
确保初始化了构造函数中的每个类成员
不要忘记删除你的第一级指针指向的内存(析构函数的最后一行)
如果你不需要
,不要使用明确的关于复制和移动语义呢?
new
和delete
为了使用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;
}
请注意,这段代码仅用于演示目的,仍然缺乏重要的方面,不应该在实际应用程序中使用。
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 没有显式声明的int[]中的foreach
- 在c++中访问int到类对象的映射时出错
- 为什么我无法更改"set<set>"循环中的值<int>
- EASTL矢量<向量<int>>连续的
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- 'structstd::对<int,int>'没有名为'push_back'