我将在我的C ++应用程序中大量使用一些C-API,我有很多可用的函数,我需要调用它们。例如,开始时为createFoo(void *),作业完成时为freeFoo(void *)。
所以,我想使用RAII习语,所以我创建了第一个包含复制构造函数和赋值运算符私有的包装器而没有实现。它工作正常,但我想要更丰富的复制语义。我想使用引用计数复制语义。我考虑过写自己的版本,但我不想重新发明轮子。此外,boost :: shared_ptr已经实现了我想要实现的几乎所有的行为。
唯一的区别是指针不是用new创建的,它不是用delete删除的。我想自定义源和接收器功能。
我觉得这是一个很好的方式来面对这个问题,但我无法想出一个实现我的想法的课程。
以下是问题,您认为这是解决问题的好方法吗?是否有任何开源代码实现类似的东西?你有任何提示吗?
由于
答案 0 :(得分:8)
这真的很容易。例如,假设您有C fopen接口:
FILE* fopen(blah);
int fclose(FILE*);
然后你可以像这样用shared_ptr包装FILE资源:
shared_ptr<FILE> ptr(fopen("file.txt", "rt"), fclose);
// use the file pointed by ptr
fwrite(..., ptr.get());
// FILE is automatically closed by a call to fclose when
// reference count drops to zero...
编辑:让我解释一下。shared_ptr
存储'删除'以及所有权和弱所有权的参考计数器。删除器是可以使用指向要作为参数释放的资源的指针调用的任何对象。默认删除器只是在其参数上调用delete
,但是您可以传递自己的删除器。
当我应用上面的技术时,我通常将创建包装到一个单独的函数中。这简化了代码,并允许我检查从C风格的API返回的错误代码并将它们转换为异常:
shared_ptr<FILE> MakeFile(const char* name, const char* mod)
{
if(FILE *ptr = fopen(name, mod))
return shared_ptr<FILE>(ptr, fclose);
throw SomeExceptionType("fopen", errno, ...);
}