如何为 unique_ptr 管理的数组编写自定义删除器?
How can I write a custom deleter for an array managed by an unique_ptr?
我正在尝试找到一种方法来为模板化 C++ class 中的 unique_ptr 管理的 C 数组编写自定义删除器。我故意让删除器什么也不做,从而使 class 内存泄漏。在完整的 class 中,一些构造函数分配内存,而另一些则不分配 - 而是它们使用来自数据流的原始字节缓冲区中的内存。
这是我试过的:
template <class T> class Matrix
{
private:
int _size;
std::unique_ptr<T[]> _array;
public:
Matrix(int size, void* data) : _size(size)
, _array(NULL, [](T[]* p){})
{
_array.reset((T*)data);
}
};
代码编译不通过,报错信息为:
In file included from /tmp/test/test/test.cpp:9:
/tmp/test/test/Matrix.h:22:55: error: expected ')'
, _array(NULL, [](T[]* p){})
^
/tmp/test/test/Matrix.h:22:51: note: to match this '('
, _array(NULL, [](T[]* p){})
^
1 error generated.
首先,始终创建一个简单的设置来测试事物:
int main() {
using T = int;
std::unique_ptr<T[]> _array(NULL, [](T[]* p){});
return 0;
}
现在解决你的问题:
T[]* p
无效,应为 T* p
.
- 您作为删除器传递的 lambda 与用作默认删除器的
std::default_delete<T>
不匹配。所以你必须写std::unique_ptr<T[],std::function<void(T*)>
。
- 和
NULL
可能被实现为整数类型,所以你应该使用 nullptr
代替,否则 gcc
不会编译你的代码(因为 c++11 你,一般来说,应该使用 nullptr
而不是 NULL
).
所以把所有东西放在一起你会得到:
int main() {
using T = int;
std::unique_ptr<T[],std::function<void(T[])>> _array(nullptr, [](T* p){});
return 0;
}
删除器是std::unique_ptr
的模板参数。默认情况下它是 std::default_delete
,但您可以指定不同的内容,例如
template <typename T>
struct NonDeleter
{
void operator()(T*) { /* nothing */ }
};
template <typename T>
struct NonDeleter<T[]> : NonDeleter<T> {};
template <class T> class Matrix
{
private:
int _size;
std::unique_ptr<T[], NonDeleter<T[]>> _array;
public:
Matrix(int size, void* data) : _size(size)
, _array(static_cast<T*>(data))
{
}
};
我正在尝试找到一种方法来为模板化 C++ class 中的 unique_ptr 管理的 C 数组编写自定义删除器。我故意让删除器什么也不做,从而使 class 内存泄漏。在完整的 class 中,一些构造函数分配内存,而另一些则不分配 - 而是它们使用来自数据流的原始字节缓冲区中的内存。
这是我试过的:
template <class T> class Matrix
{
private:
int _size;
std::unique_ptr<T[]> _array;
public:
Matrix(int size, void* data) : _size(size)
, _array(NULL, [](T[]* p){})
{
_array.reset((T*)data);
}
};
代码编译不通过,报错信息为:
In file included from /tmp/test/test/test.cpp:9:
/tmp/test/test/Matrix.h:22:55: error: expected ')'
, _array(NULL, [](T[]* p){})
^
/tmp/test/test/Matrix.h:22:51: note: to match this '('
, _array(NULL, [](T[]* p){})
^
1 error generated.
首先,始终创建一个简单的设置来测试事物:
int main() {
using T = int;
std::unique_ptr<T[]> _array(NULL, [](T[]* p){});
return 0;
}
现在解决你的问题:
T[]* p
无效,应为T* p
.- 您作为删除器传递的 lambda 与用作默认删除器的
std::default_delete<T>
不匹配。所以你必须写std::unique_ptr<T[],std::function<void(T*)>
。 - 和
NULL
可能被实现为整数类型,所以你应该使用nullptr
代替,否则gcc
不会编译你的代码(因为 c++11 你,一般来说,应该使用nullptr
而不是NULL
).
所以把所有东西放在一起你会得到:
int main() {
using T = int;
std::unique_ptr<T[],std::function<void(T[])>> _array(nullptr, [](T* p){});
return 0;
}
删除器是std::unique_ptr
的模板参数。默认情况下它是 std::default_delete
,但您可以指定不同的内容,例如
template <typename T>
struct NonDeleter
{
void operator()(T*) { /* nothing */ }
};
template <typename T>
struct NonDeleter<T[]> : NonDeleter<T> {};
template <class T> class Matrix
{
private:
int _size;
std::unique_ptr<T[], NonDeleter<T[]>> _array;
public:
Matrix(int size, void* data) : _size(size)
, _array(static_cast<T*>(data))
{
}
};