我想为net-snmp C库struct snmp_pdu对象实现RAII机制。

该对象是通过称为struct snmp_pdu* snmp_pdu_create(int type)的方法创建的,并通过void snmp_free_pdu(struct snmp_pdu *obj)方法释放的。

我所做的是扩展auto_ptr以在析构函数中调用方法libname_free_obj。下面是代码:

class auto_snmp_pdu : public std::auto_ptr<snmp_pdu>
{
  public:
   virtual ~auto_snmp_pdu()
   {
     snmp_free_pdu(get());
   }
};


以上是正确的吗?

编辑

我无法使用unique_ptr,因为我使用的是旧版本的g ++,并且我无权对其进行更新。

最佳答案

已弃用auto_ptr并且容易出错。将unique_ptr与自定义删除器一起使用。这是一个实现:

#include <memory>
extern "C" {
    struct snmp_pdu;

    struct snmp_pdu* snmp_pdu_create(int type);
    void snmp_free_pdu(struct snmp_pdu *obj);
}

struct snmp_pdu_deleter
{
    void operator()(snmp_pdu* p) const noexcept {
        snmp_free_pdu(p);
    }
};
using snmp_pdu_ptr = std::unique_ptr<snmp_pdu, snmp_pdu_deleter>;

snmp_pdu_ptr create_snmp_pdu(int x) {
    return snmp_pdu_ptr(snmp_pdu_create(x));
}


int main()
{
    auto ptr = create_snmp_pdu(0);
}



  
    但是我的编译器是C ++ 11之前的版本
  


unique_ptrmove语义很容易模拟:

#include <utility>
#include <iostream>
#include <stdlib.h>

extern "C" {
    struct snmp_pdu {};

    void foo(snmp_pdu*) { std::cout << "foo" << std::endl; }

    struct snmp_pdu* snmp_pdu_create(int type) {
        return (snmp_pdu*)malloc(sizeof(snmp_pdu));
    }
    void snmp_free_pdu(struct snmp_pdu *obj) {
        free(obj);
    }
}

struct snmp_pdu_proxy
{
    struct mover {
        mover(snmp_pdu*& impl_ref) : impl_ref_(impl_ref) {}
        snmp_pdu*& impl_ref_;
        };

    snmp_pdu_proxy(int code)
    : impl_(snmp_pdu_create(code))
    {}

    snmp_pdu_proxy(mover m)
    : impl_(0)
    {
        std::swap(impl_, m.impl_ref_);
    }

    mover move() {
        return mover ( impl_ );
    }

    snmp_pdu_proxy& operator=(mover m)
    {
        snmp_pdu_proxy tmp = move();
        std::swap(m.impl_ref_, impl_);
        return *this;
    }

    operator snmp_pdu* () const {
        return impl_;
    }

    ~snmp_pdu_proxy() {
        if(impl_) {
            snmp_free_pdu(impl_);
        }
    }
private:
    snmp_pdu_proxy& operator=(const snmp_pdu_proxy&);
    snmp_pdu* impl_;
};


int main()
{
    snmp_pdu_proxy ptr = snmp_pdu_proxy(0);

    snmp_pdu_proxy p2 = ptr.move();

    ptr = p2.move();

    foo(ptr);
}

关于c++ - 扩展auto_ptr以释放C样式的对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45478589/

10-11 23:17
查看更多