1
votes

I have a legacy class whose lifetime is managed by reference counting (it derives from ACE_Event_Handler, to be precise).

I want to be able to manage it using std::shared_ptr in my code but still keep the old legacy reference counting (objects of the class need to be accessed by a third-party library that doesn't accept shared_ptr - ACE, to be precise).

An object must be deleted when the reference count drops to 0 and all of the shared_ptr instances managing it get destroyed.

I have only one idea: keep an instance of shared_ptr pointing to the object until the reference count drops to 0 and then reset it. Somehow, this feel dirty. Is there a better way?

1
Why not write a smart pointer which handles incrementing and decrementing the ACE reference count, and use that? It's easy enough. - Martin Bonner supports Monica
I'd like to use std::shared_ptr. - Gbr
Something like boost::intrusive_ptr seems like a better fit than std::shared_ptr. If boost isn't an option, then rolling your own instrusive_ptr-like class is probably your only option. - Miles Budnek
I read about it and even thought of formulating the question as using intrusive_ptr and shared_ptr simultaneously. It looks like I need to use either std::shared_ptr or intrusive_ptr throughout all of my code and I prefer the former. - Gbr
Why do you want to use shared_ptr? This feels like an X-Y problem. - Martin Bonner supports Monica

1 Answers

1
votes

The normal approach would be to have your own custom ptr implementation with ACE_Event_Handler::add_ref() in the constructor and ACE_Event_Handler::release() in the destructor.

Alternatively, you can use std::unqiue_ptr with custom deleter:

template<typename T>
struct custom_releaser
{
    void operator()(T *p) { if (p) p->release(); }
};

std::unique_ptr<T, custom_releaser<T>> my_ptr;

If you really want std::shared_ptr:

std::shared_ptr<T> ptr = std::shared_ptr(std::move(my_ptr));

I wonder, however, if it will properly call ACE_Event_Handler::add_ref(). I guess, std::shared_ptr will ref count based on it's own member variable - so that you would need to provide a method to do ACE_Event_Handler::add_ref() when creating an instance and adding ref counts.