Often you can use a pattern like this:
class C {
public:
void foo() {
underlying_foo(handle.get());
}
void bar() {
// transfers ownership
underlying_bar(handle.release());
}
// use default copy/move constructor and assignment operator
private:
struct deleter {
void operator()(T* ptr) {
deleter_fn(ptr);
}
};
std::unique_ptr<T, deleter> handle;
};
By using release
you can explicitly transfer ownership. However this is confusing and you should avoid it if at all possible.
Most C libraries have a C++-like object life cycle (object allocation, accessors, destruction) that maps nicely onto the C++ pattern without ownership transfer.
If users need shared ownership, they should use shared_ptr
with your classes. Don't try to implement any ownership sharing yourself.
Update: If you want to make the transfer of ownership more explicit, you can use a reference qualifier:
void bar() && { ... }
Then users must call bar
on lvalues like this:
C o;
std::move(o).bar(); // transfer of ownership is explicit at call site