auto_ptr
is deprecated and bug-prone. Use unique_ptr
with a custom deleter. Here is one implementation:
#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);
}
but my compiler is pre-c++11
unique_ptr
and move
semantics are fairly easy to simulate:
#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);
}