2017-08-14 137 views
2

我想实现一个C++类,其目的是实现C风格对象的RAII机制。在C++中为C风格对象创建透明包装类

然后,我需要能够将此类的实例传递给所有接收提到的C风格对象作为参数的C风格函数。我知道这应该用unique_ptr解决,但现在我不能使用C++11。无论如何,我想了解如何做到这一点,不管有没有更好的解决方案。

我有几个怀疑,关于我必须重载哪些操作员,以及他们之间的差异。

下面是我使用的实现代码示例。我特别与运营商1和2(有什么区别?)

我想知道,如果我已经实现的代码涵盖了所有的用例,我的意思是,所有的情况下,C库可以使用目的。此外,我想了解运营商1和2

C-Style对象

// Example: a C-style library called "clib" which use an object called "cobj": 

struct cobj { 
    int n;  
}; 

void clib_create_cobj(struct cobj **obj) { 
    *obj = (struct cobj*)malloc(sizeof(cobj)); 
    (*obj)->n = 25; 
} 

void clib_release_cobj(struct cobj *obj) { 
    free(obj); 
} 

void clib_doSomething(struct cobj *obj) { 
    std::cout << obj->n << std::endl; 
} 

C++ “透明” 包装

// My wrapper class for implementing RAII 

class CobjWrapper { 
    public: 
     CobjWrapper(struct cobj *obj) : m_obj (obj) { } 

     ~CobjWrapper() { 
      if(m_obj != NULL) { 
       clib_release_cobj(m_obj); 
       m_obj = NULL; 
      } 
     } 


     operator struct cobj*() const { // (1) 
      return m_obj; 
     } 

     struct cobj& operator *() {  // (2) 
      return *m_obj; 
     } 

     struct cobj** operator &() {  // (3) 
      return &m_obj; 
     } 

     struct cobj* operator->() {  // (4) 
      return m_obj; 
     } 

    private: 
     struct cobj *m_obj; 

}; 

主要方法

之间的差
// The main method: 

int main() { 
    struct cobj *obj = NULL; 

    clib_create_cobj(&obj); 

    CobjWrapper w(obj); 
    clib_doSomething(w); 

    return 0; 
} 

上面的来源可以在这里测试:

http://cpp.sh/8nue3

+0

请您制定一个清晰的问题?你想知道(1)和(2)之间的区别吗?现在,你不是在问什么,而只是说出你不知道的东西。 – idmean

+0

如果您要实施RAII,您应该知道*三/五/零*的规则是什么。无论如何,已经有'std :: unique_ptr'这个定制的删除器。 – LogicStuff

+0

仅供参考:C++ 98有'std :: auto_ptr'而不是'std :: unique_ptr'。 – Zefick

回答

3

下面是一个隐式转换

operator struct cobj*() const { // (1) 

与示例用法

CobjWrapper wrapper = /**/; 

struct cobj* obj = wrapper; 

而下面是一元operator *

struct cobj& operator *() {  // (2) 

与用法示例

CobjWrapper wrapper = /**/; 

struct cobj& obj = *wrapper; 

BTW,我会完全隐藏的C结构,像:

class CobjWrapper { 

    struct ObjDeleter 
    { 
     void operator()(cobj *obj) const { clib_release_cobj(obj); } 
    }; 

    public: 
     CobjWrapper() 
     { 
      cobj *obj = nullptr; 
      clib_create_cobj(&obj); 
      m_obj.reset(obj); 
     } 

     void doSomething() { clib_doSomething(m_obj.get()); } 

    private: 
     std::unique_ptr<cobj, ObjDeleter> m_obj; 
};