lundi 28 novembre 2016

C++ safely deleting event object paylod with shared_ptr

I need to create an Event object to be dispatched by an event listener system. The Event needs to have following properties:

  1. Event can potentially be handled by 0..n listener objects.
  2. Event contains a void pointer which can point to an arbitrary object (payload) (unknown type at build time). Event listener will convert to appropriate type depending on Event's name.
  3. Need the payload object to be (automatically) deleted once the event has been dispatched to interested parties. Original event raiser cannot deallocate as event goes into an asvnc queue.
  4. Assume listeners can make shallow copy of payload when event is processed.

I have implemented the solution here, but AFAIK this causes the payload to be deallocated (via the unique_ptr) after the first event handler.

In the code below, 'setData' attempts to take the payload object (dataObject), and to convert it into a shared_ptr to be carried by void* data. getData does the "reverse":

class Event {

public:
std::string name;

Event(std::string n = "Unknown", void* d = nullptr) :name(n), data(d) {}

template<class T>  void setData(const T dataObject)
{
    //Create a new object to store the data, pointed to by smart pointer
    std::shared_ptr<T> object_ptr(new T);
    //clone the data into the new object
    *object_ptr = dataObject;

    //data will point to the shared_pointer
    data= new std::shared_ptr<T>(object_ptr);
}


//reverse of setData.
template<class T>  T getData() const
{
    std::unique_ptr<
        std::shared_ptr<T>
        > data_ptr((std::shared_ptr<T>*) data);
    std::shared_ptr<T> object_ptr = *data_ptr;

    return *object_ptr;
}

private:
    void* data;
}; 

Aucun commentaire:

Enregistrer un commentaire