C++ RAII的Wrap C分配

C++ RAII的Wrap C分配,c++,c++11,smart-pointers,C++,C++11,Smart Pointers,我从一个库中获得了这些普通C函数: struct SAlloc; SAlloc *new_salloc(); void free_salloc(SAlloc *s); 有什么方法可以将C++中的这个包封装到智能指针(STD::UnQuijpTR),或者以其他方式RAII包装?< /P> 我主要好奇的是,在不创建自己的包装器/类的情况下,标准库的可能性。是的,您可以为此重用unique\u ptr。只需定制一个删除器 struct salloc_deleter { void oper

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

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

有什么方法可以将C++中的这个包封装到智能指针(STD::UnQuijpTR),或者以其他方式RAII包装?< /P>


我主要好奇的是,在不创建自己的包装器/类的情况下,标准库的可能性。

是的,您可以为此重用unique\u 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>;
struct salloc\u deleter{
void运算符()(SAlloc*s)常量{
free_salloc(s);//返回值究竟是什么?
}
}
使用salloc_ptr=std::unique_ptr;

我喜欢R.Martinho Fernandes的答案,但这里有一个较短(但效率较低)的选择:

auto my_alloc = std::shared_ptr<SAlloc>(new_salloc(), free_salloc);
auto my_alloc=std::shared_ptr(new_salloc(),free_salloc);

有什么方法可以将C++中的这个包封装到智能指针(<代码> STD::UnQuyPPTR <代码>),或者以其他方式RAII包装?< /P> 对。这里需要一个工厂函数,该函数创建正确初始化智能指针的对象(并确保始终正确构造指针实例):

std::shared_ptr make_shared_salloc()
{
返回std::shared_ptr(new_salloc(),free_salloc);
}
//注:这不起作用(见下面@R.MartinhoFernandes的评论)
std::unique_ptr make_unique_salloc()
{
返回std::unique_ptr(new_salloc(),free_salloc);
}
您可以将调用这些函数的结果分配给其他智能指针(根据需要),指针将被正确删除

编辑: 或者,您可以为您的SAlloc指定
std::make_shared

编辑2: 第二个函数(
make_unique_salloc
)未编译。需要实现另一个deleter functor来支持实现。

另一个变体:

#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{
int x;
};
SAlloc*new_SAlloc(){返回新的SAlloc();}
void free_salloc(salloc*s){delete s;}
结构salloc_freer{
void运算符()(SAlloc*s)常量{free_SAlloc(s);}
};
typedef std::unique_ptr unique_salloc;
模板
唯一的_sallocmake _salloc(Args&&…Args){
auto retval=unique_salloc(new_salloc());
如果(返回){
*retval=SAlloc{std::forward——这些的实现并不重要


只要您能看到
SAlloc
的成员,上面的内容就可以让您在创建
SAlloc
的同时像在初始值设定项列表中一样构造它们,如果您不传入任何参数,那么出于好奇,整个
SAlloc
结构将归零,
free\u SAlloc()
return?您可能会以某种方式使用boost::intrusive\u ptr。很抱歉,它应该是免费的\u salloc()那里的
free\u-salloc
不是一种类型,所以不是。你可以使用
std::unique\u ptr;
,但是你必须手动将
free\u-salloc
传递给每个构造函数。使用RAII返回值没有意义。它们是不兼容的想法。+1顺便说一句!谢谢你的回答。我问过
std::unique\u ptr
是否也能工作但是在发布后就意识到了这个错误,所以我删除了我的评论。你不需要一个salloc_deleter functor-你只需要将free_salloc函数作为一个deleter传递(见下面我的答案)。您可以在此处使用
std::integral\u constant
,有关详细信息,请参阅。
free\u salloc
不是
default\u delete
的实例,因此第二个函数不会编译。@R.MartinhoFernandes,我不确定您所说的“default\u delete实例”是什么意思.shared_ptr/unique_ptr可与任何deleter函子一起工作。
default_delete
default_array_delete
是简单的函子,没有特殊要求,可以被任何其他尊重相同签名的函子类型所取代。请参见此处作为OP询问的示例:这是错误的。unique_ptr仅在h类型为D的删除器。唯一\u ptr仅适用于默认\u delete类型的删除器:
#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);
}