编写C库…的…包装器有一个常见的问题我的主存储器是一个class指针,它总是代表一个C++类,只包含一个数据字段。
class MyClassC {
struct MyStructS * hdl
...
}创建所有构造函数、静态函数和方法函数都不是问题,…我的设计问题现在是…是使用值类设计还是指针类设计。
值类总是返回对象,而不是指针:
一个值类有一个ONE来 MyStructS和MyClassC之间的多个关系。
MyClassC myMethod () {
...
return MyClassC(struct MyStructS *...);
}值类的析构函数从不释放 struct MyStructS指针,并且大部分为空。
值的析构函数是一个静态或方法,主要称为destry或delete。
MyClassC::delete() {
DestroyMyPointer(&hdl)
}
...
MyClassC obj = {...};
...
obj.delete();
...value类是方法的参数,也是一个值:
some_proc_or_method (MyClassC arg1, MyClassC arg2, …) {
...
} 还有另外一个问题:
如何为值类参数创建默认参数?
some_proc_or_method (MyClassC arg1, MyClassC arg2 = MyClassC {...} ???? ) {
...
} 类总是返回对象的指针:
指针类具有ONE to ONE MyStructS和MyClassC之间的关系。
MyClassC* myMethod () {
...
return this or getThisFrom(myStructS_pointer)
}指针类的析构函数始终是空闲的结构MyStructS指针
~MqClassC () {
DestroyMyPointer(&hdl)
}
...
MyClassC* obj = new MyClassC(...);
...
delete obj;
...发布于 2018-06-17 10:01:47
我会选择选项3:首先获得正确所有权的薄包装器。C代码在C++中已经很有用了。从包装中获得的唯一实际好处是获得所有权语义的正确。这两种方法都试图将跟踪所有权的责任放在API的用户身上。这不是一个有用的包装器,它只是添加了一个多余的间接层。您的客户端仍然需要考虑C API的内部结构才能有效。
相反,我建议您返回一个具有明确所有权语义的智能指针。编写一堆接受智能指针并转发到C的内联空闲函数。最终的结果是,您拥有几乎相同的API (较少的学习曲线),具有C++所有权语义。这是一项收获,结果就不会那么麻烦了。
#include <memory>
#include <CLibAPI.h>
namespace CPPWrapC {
namespace detail {
struct DestroyMyPointer {
void operator()(MyStructS *hdl) {
::DestroyMyPointer(&hdl);
}
};
}
using Handle = std::unique_ptr<MyStructS, detail::DestroyMyPointer>;
Handle myMethod() {
MyStructS *ret = /* init it */;
return Handle{ret};
}
inline void some_proc_or_method(Handle const& hdl) {
c_lib_some_proc_or_method(hdl.get());
}
}因此,现在您有了一个简单的包装器,它支持单所有权语义处理。我想正是你想要的。使用它与使用原始包装API几乎完全一样,因此客户端可以利用他们所知道的任何关于C库的信息来工作。
这可以作为一个垫脚石。现在您有了一个C++类型,您可以将它作为一个成员来进一步包装。
https://stackoverflow.com/questions/50895375
复制相似问题