【问题标题】:Create a transparent wrapper class in C++ for a C-style object在 C++ 中为 C 风格的对象创建一个透明的包装类
【发布时间】:2017-08-14 08:13:41
【问题描述】:

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

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

对于我必须重载哪些运算符以及其中一些运算符之间的区别,我有几个疑问。

下面是我实现的代码示例。我对运算符 1 和 2 感到特别困惑(有什么区别?)

我想知道我实现的代码是否涵盖了所有用例,我的意思是,C 库可以使用该对象的所有场景。另外想了解一下操作符1和2的区别。

C 风格对象

// 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

【问题讨论】:

  • 您能提出一个明确的问题吗?您想知道(1)和(2)之间的区别吗?现在,你并没有真正问什么,只是说你不知道的。
  • 如果你要实施RAII,你应该知道三/五/零规则是什么。无论如何,已经有 std::unique_ptr 有一个自定义删除器。
  • 仅供参考:C++98 有 std::auto_ptr 而不是 std::unique_ptr

标签: c++ c operator-overloading raii


【解决方案1】:

以下是一个隐式转换

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

示例用法

CobjWrapper wrapper = /**/;

struct cobj* obj = wrapper;

而以下是一元operator *

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

示例用法

CobjWrapper wrapper = /**/;

struct cobj& obj = *wrapper;

顺便说一句,我会完全隐藏 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;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-30
    • 2019-07-29
    • 1970-01-01
    相关资源
    最近更新 更多