jeudi 11 février 2021

C++ custom signal/slots destructor problem

Im working on signal/slots module in my embedded project (no std lib). It works fine but Ive noticed that I need to release slot when its object is destroyed. I have slot list in "memberSlots" named variable. Slot is a pair of object and a pointer to its member function. Slot executes member function by "call" method. The problem is that when slots "target" object is destroyed its not going to be removed from memberSlots list in signal aka it will try to execute member function from destroyed object pointer when emit on signal is called.

signal.h:

#include "slot.h"
#include "list.h"

template<typename Arg, typename RetType = void>
class Signal
{
    List<SlotInterface<Arg>*> memberSlots;
    List<RetType(*)(Arg)> nonMemberSlots;
public:
    ~Signal() {
        for (auto slot : memberSlots) delete slot;
    }
    template<typename Type>
    void attach(Type* object, RetType(Type::* m)(Arg)) {
        nonMemberSlots.pushBack(m);
    }
    void attach(RetType(*m)(Arg)) {
        memberSlots.pushBack(new Slot<Type, Arg, RetType>(object, m));
    }
    void emit(const Arg& arg) {
        for (auto slot : memberSlots) slot->call(arg);
        for (auto slot : nonMemberSlots) slot(arg);
    }
};

slot.h:

template <typename T>
class SlotInterface {
public:
    virtual ~SlotInterface(){}
    virtual void call(T value) = 0;
};

template <typename Target, typename ArgType, typename RetType=void>
class Slot : public SlotInterface<ArgType>
{
    Target* object;
    RetType (Target::*method)(ArgType);
public:
    Slot(Target* object, RetType (Target::*m)(ArgType)) : object(object), method(m) {}
    void call(ArgType value) override {
        (object->*method)(value);
    }
};

Is there any reliable solution to make it remove slot when target class is being destroyed or anything similar? I dont want to deattach slot manually since I would own a pointer then and Im trying to avoid this kind of situation.

Aucun commentaire:

Enregistrer un commentaire