7

我从库中获得了这些普通的 C 函数:

struct SAlloc;
SAlloc *new_salloc();
void   free_salloc(SAlloc *s);

有什么方法可以在 C++ 中将其包装为智能指针(std::unique_ptr)或 RAII 包装器?

我主要对标准库的可能性感到好奇,而无需创建自己的包装器/类。

4

4 回答 4

14

是的,您可以为此重用 unique_ptr。只需制作一个自定义删除器。

struct salloc_deleter {
    void operator()(SAlloc* s) const {
        free_salloc(s); // what the heck is the return value for?
    }
}

using salloc_ptr = std::unique_ptr<SAlloc, salloc_deleter>;
于 2013-02-11T09:01:47.527 回答
3

我喜欢 R. Martinho Fernandes 的回答,但这里有一个更短(但效率更低)的替代方案:

auto my_alloc = std::shared_ptr<SAlloc>(new_salloc(), free_salloc);
于 2013-02-11T09:25:11.823 回答
0

有什么方法可以在 C++ 中将它包装到智能指针 ( std::unique_ptr) 或 RAII 包装器中?

是的。您在这里需要一个工厂函数,它创建正确初始化智能指针的对象(并确保您始终正确构造指针实例):

std::shared_ptr<SAlloc> make_shared_salloc()
{
    return std::shared_ptr<SAlloc>(new_salloc(), free_salloc);
}

// Note: this doesn't work (see comment from @R.MartinhoFernandes below)
std::unique_ptr<SAlloc> make_unique_salloc()
{
    return std::unique_ptr<SAlloc>(new_salloc(), free_salloc);
}

您可以将调用这些函数的结果分配给其他智能指针(根据需要),这些指针将被正确删除。

编辑:或者,您可以std::make_shared针对您的 SAlloc 进行详细说明。

编辑 2:第二个函数 ( make_unique_salloc) 无法编译。需要实现一个替代的删除器函子来支持实现。

于 2013-02-11T09:41:59.427 回答
0

另一种变化:

#include <memory>

struct SAlloc {
  int x;
};
SAlloc *new_salloc() { return new SAlloc(); }
void   free_salloc(SAlloc *s) { delete s; }

struct salloc_freer {
  void operator()(SAlloc* s) const { free_salloc(s); }
};
typedef std::unique_ptr<SAlloc, salloc_freer> unique_salloc;
template<typename... Args>
unique_salloc make_salloc(Args&&... args) {
  auto retval = unique_salloc( new_salloc() );
  if(retval) {
    *retval = SAlloc{std::forward<Args>(args)...};
  }
  return retval;
}

int main() {
   unique_salloc u = make_salloc(7);
}

我包含了一个主体SAlloc和各种功能,使其成为http://sscce.org/——这些的实现并不重要。

只要您可以看到 的成员SAlloc,上面的内容就可以让您在创建 的同时构造它们,就像在初始化列表中一样SAlloc,如果您不传入任何参数,它会将整个SAlloc struct.

于 2013-02-11T12:50:32.887 回答