首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >资源-代理类…C++最佳实践

资源-代理类…C++最佳实践
EN

Stack Overflow用户
提问于 2018-06-17 09:31:38
回答 1查看 196关注 1票数 0

编写C库…的…包装器有一个常见的问题我的主存储器是一个class指针,它总是代表一个C++类,只包含一个数据字段。

代码语言:javascript
复制
class MyClassC {
  struct MyStructS * hdl
  ...
}

创建所有构造函数、静态函数和方法函数都不是问题,…我的设计问题现在是…是使用值类设计还是指针类设计。

值类总是返回对象,而不是指针:

一个值类有一个ONE MyStructS和MyClassC之间的多个关系。

代码语言:javascript
复制
MyClassC myMethod () {
  ...
  return MyClassC(struct MyStructS *...);
}

值类的析构函数从不释放 struct MyStructS指针,并且大部分为空。

值的析构函数是一个静态或方法,主要称为destry或delete。

代码语言:javascript
复制
MyClassC::delete() {
   DestroyMyPointer(&hdl)
}
...
MyClassC obj = {...};
...
obj.delete();
...

value类是方法的参数,也是一个值:

代码语言:javascript
复制
some_proc_or_method (MyClassC arg1, MyClassC arg2, …) {
   ...
} 

还有另外一个问题:

如何为值类参数创建默认参数?

代码语言:javascript
复制
some_proc_or_method (MyClassC arg1, MyClassC arg2 = MyClassC {...} ???? ) {
   ...
} 

类总是返回对象的指针:

指针类具有ONE to ONE MyStructS和MyClassC之间的关系。

代码语言:javascript
复制
MyClassC* myMethod () {
  ...
  return this or getThisFrom(myStructS_pointer)
}

指针类的析构函数始终是空闲的结构MyStructS指针

代码语言:javascript
复制
~MqClassC () {
   DestroyMyPointer(&hdl)
 }

...
MyClassC* obj = new MyClassC(...);
...
delete obj;
...
EN

回答 1

Stack Overflow用户

发布于 2018-06-17 10:01:47

我会选择选项3:首先获得正确所有权的薄包装器。C代码在C++中已经很有用了。从包装中获得的唯一实际好处是获得所有权语义的正确。这两种方法都试图将跟踪所有权的责任放在API的用户身上。这不是一个有用的包装器,它只是添加了一个多余的间接层。您的客户端仍然需要考虑C API的内部结构才能有效。

相反,我建议您返回一个具有明确所有权语义的智能指针。编写一堆接受智能指针并转发到C的内联空闲函数。最终的结果是,您拥有几乎相同的API (较少的学习曲线),具有C++所有权语义。这是一项收获,结果就不会那么麻烦了。

代码语言:javascript
复制
#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++类型,您可以将它作为一个成员来进一步包装。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50895375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档