我从库中获得了这些普通的 C 函数:
struct SAlloc;
SAlloc *new_salloc();
void free_salloc(SAlloc *s);
有什么方法可以在 C++ 中将其包装为智能指针(std::unique_ptr)或 RAII 包装器?
我主要对标准库的可能性感到好奇,而无需创建自己的包装器/类。
我从库中获得了这些普通的 C 函数:
struct SAlloc;
SAlloc *new_salloc();
void free_salloc(SAlloc *s);
有什么方法可以在 C++ 中将其包装为智能指针(std::unique_ptr)或 RAII 包装器?
我主要对标准库的可能性感到好奇,而无需创建自己的包装器/类。
是的,您可以为此重用 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>;
我喜欢 R. Martinho Fernandes 的回答,但这里有一个更短(但效率更低)的替代方案:
auto my_alloc = std::shared_ptr<SAlloc>(new_salloc(), free_salloc);
有什么方法可以在 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
) 无法编译。需要实现一个替代的删除器函子来支持实现。
另一种变化:
#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
.