我想为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_ptr
和move
语义很容易模拟:#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/