首页 > 解决方案 > 如何为由 unique_ptr 管理的数组编写自定义删除器?

问题描述

我正在尝试找到一种方法来为模板化 C++ 类中由 unique_ptr 管理的 C 数组编写自定义删除器。我故意试图通过让删除器什么都不做来使类泄漏内存。在完整类中,一些构造函数分配内存,而另一些则不分配 - 相反,它们利用来自数据流的原始字节缓冲区中的内存。

这是我尝试过的:

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.

标签: c++destructorunique-ptr

解决方案


首先,始终创建一个简单的设置来测试事物:

int main() {
    using T = int;

    std::unique_ptr<T[]> _array(NULL, [](T[]* p){});

    return 0;
}

所以现在你的问题:

  • T[]* p无效,应该是T* p
  • std::default_delete<T>您作为删除器传递的 lambda 与用作默认删除器的 lambda 不匹配。所以你必须写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;
}

推荐阅读