我意识到有人问过elsewhere类似的问题,但我找不到一个适合我的函数签名的答案。
考虑下面这对典型的C函数:
int initFoo(Options options, Foo* foo);
void freeFoo(Foo* foo);
initFoo
接受一些选项和一个指向未初始化的Foo
结构的指针。它初始化此结构并返回指示初始化是否成功的结果代码。freeFoo
释放已初始化的Foo
结构。
现在假设我想在C++代码中使用这些C函数。我想使用RAII,所以我需要构造一个在销毁时自动调用freeFoo
的unique_ptr<Foo>
。我能想到的最好的方法是:
template<typename T>
using lambda_unique_ptr = std::unique_ptr<T, std::function<void(T*)>>;
lambda_unique_ptr<Foo> createFoo(Options options) {
Foo* foo = new Foo();
const int resultCode = initFoo(options, foo);
if (resultCode != 0) throw ...;
return lambda_unique_ptr<Foo>(foo, [](Foo* foo) {
freeFoo(foo);
delete foo;
});
}
我确信一定会有一个更优雅的解决方案。理想情况下,一些功能更强大的东西不需要这么多单独的步骤。我发现特别难看的是必须显式地在堆上分配Foo
结构,然后分两步显式地释放和删除它。有什么想法吗?
发布于 2018-06-09 04:56:58
你就不能把Foo
包装在一个类里吗?
struct FooWrap {
Foo foo;
explicit FooWrap(Options options) {
if (initFoo(options, &this->foo))
throw ...;
}
~FooWrap() {
freeFoo(&this->foo);
}
// XXX: either implement or disable assignment and copy construction
};
现在,您可以选择是只将FooWrap x(42);
定义为自动变量,还是使用new
动态分配它。
https://stackoverflow.com/questions/50768125
复制相似问题