Suppose a C API provides an opaque struct with internal reference counting:
struct Opaque {
int data;
int refcount;
};
struct Opaque* opaque_new(int data) {
return new Opaque {
.data = data,
.refcount = 1
};
}
int opaque_data(struct Opaque* opaque) {
return opaque->data;
}
struct Opaque* opaque_ref(struct Opaque* opaque) {
opaque->refcount++;
return opaque;
}
void opaque_unref(struct Opaque* opaque) {
opaque->refcount--;
if (!opaque->refcount) {
delete opaque;
}
}
How to create a wrapper type that is copyable, movable, copy assignable and move assignable?
So far I have:
#include <algorithm>
class Wrapper {
public:
Wrapper() : m_opaque(nullptr) {}
explicit Wrapper(int data) : m_opaque(opaque_new(data)) {}
Wrapper(const Wrapper&) = delete; // TODO
Wrapper(Wrapper&& wrapper) : m_opaque(wrapper.m_opaque) {
wrapper.m_opaque = nullptr;
}
Wrapper& operator=(const Wrapper&) = delete; // TODO
Wrapper& operator=(Wrapper&& other) {
swap(other);
return *this;
}
~Wrapper() {
if (m_opaque) {
opaque_unref(m_opaque);
}
}
void swap(Wrapper& other) {
std::swap(m_opaque, other.m_opaque);
}
int getData() const {
if (m_opaque) {
return opaque_data(m_opaque);
} else {
return 0;
}
}
private:
struct Opaque* m_opaque;
};
I specifically don't want reference counting on top of reference counting, using std::shared_ptr
with a custom deleter.
What's a concise way to implement the remaining methods, in particular copy assignment? Is there a better way to implement the ones I got so far?