将std :: unique_ptr与自定义自由操作结合使用

时间:2018-01-12 09:32:11

标签: c++ c++11 unique-ptr

我有一个带有构造函数和析构函数的类,以及以下代码:

class propagation_module{
    private:
                gsl_interp_accel *xa;
                interp2d_spline *interp_s;
    public:
        propagation_module()
        {
            std::vector<int> p_N = {1, 2, 3}, z_vec = {1, 2, 3};
            xa = gsl_interp_accel_alloc();
            interp_s = interp2d_spline_alloc(interp2d_bicubic, p_N.size(), z_vec.size());
        }
        ~propagation_module(){
            gsl_interp_accel_free(xa);
            interp2d_spline_free(interp_s);
        }
}

我想用std :: unique_ptr-variables替换指针,但我不明白如何实现自由函数。根据其他一些问题,以下方式应该有效:

class propagation_module
{
    private: 
        std::unique_ptr<gls_interp_accel, decltype(&gsl_interp_accel_free)> xa;
        std::unique_ptr<interp2d_spline, decltype(&interp2d_spline_free)> interp_s;
    public:
        propagation_module()
        {
            //Same as above
        }
        //No destructor necessary
}

这是正确的,还是我忘记了什么?

1 个答案:

答案 0 :(得分:5)

你在那里。默认情况下,std::unique_ptr将在unique_ptr创建时未传递任何内容时默认构造其删除器。您为删除者提供了正确的类型,但您也需要提供他们的

public:
    propagation_module()
    {
        std::vector<int> p_N = {1, 2, 3}, z_vec = {1, 2, 3};
        xa = {gsl_interp_accel_alloc(), &gsl_interp_accel_free};
        interp_s = {interp2d_spline_alloc(interp2d_bicubic, p_N.size(), z_vec.size()), &interp2d_spline_free};
    }

或者,如果您不希望每次创建唯一指针时都必须提供正确的删除器,则可以创建默认可构造的包装器来调用正确的函数:

struct GslInterpAccelFree
{
  void operator() (gsl_interp_accel *p) const { gsl_interp_accel_free(p); }
};

struct Interp2dSplineFree
{
  void operator() (interp2d_spline *p) const { interp2d_spline_free(p); }
};

class propagation_module
{
    private: 
        std::unique_ptr<gls_interp_accel, GslInterpAccelFree> xa;
        std::unique_ptr<interp2d_spline, Interp2dSplineFree> interp_s;
    public:
        propagation_module()
        {
            std::vector<int> p_N = {1, 2, 3}, z_vec = {1, 2, 3};
            xa.reset(gsl_interp_accel_alloc());
            interp_s.reset(interp2d_spline_alloc(interp2d_bicubic, p_N.size(), z_vec.size()));
        }
        //No destructor necessary
}