Signal/Slot Best Way to Signal Using an Abstract Argument
-
I have a question on how to best go about creating a signal/slot using a base class as as the signal parameter.
So I have the following signal argument
@
enum eSignalArgumentType
{
SignalTypeOne,
SignalTypeTwo
}ISignalArgument
{
virtual eSignalArgumentType GetSignalType() = 0
}SignalOneArgument : ISignalArgument
{
eSignalArgumentType GetSignalType() { return SignalTypeOne; }...Other functions specific to the information it needs to hold...
}EmittingSignalClass
{
void EventToSignal( ISignalArgument * )
}
@Now my question is what is the best way to implement the signal emit EventToSignal(...) I want the argument of the EventToSignal to be the base class ISignalArgument because the derived argument will hold different types of information based on the what information has been processed.
If I pass the following way then the slot class will be required to handle the deleting which seems a little bit dangerous to me.
@
EmittingSignalClass
{
ProcessData( char* data)
{
... Parsing Logic ...Is of Type DataTypeOne
SignalOneArgument * arg = new SignalOneArguemnt();
emit EventToSignal( arg );... Same for other Data Types ...
}
}SlotClass
{
void OnEventSlot( ISignalArgument * arg)
{
if(arg->GetType() == SignalTypeOne)
{
SignalTypeOne * argument = reinterpret_cast<SignalTypeOne*>(arg>
HandleSignalTypeOne( argument )delete arg
}
}
}
@Is there a better way to implement this signal/slot scenario because if the signal is hooked up to multiple slots and the first one deletes the pointer it will be lost to all the rest.
-
Hi,
Don't use new, rather send a const reference to your slot. -
Then delete after emiting signal..
@SignalOneArgument * arg = new SignalOneArguemnt();
emit EventToSignal( arg );
delete arg;@ -
Yes it will not work for queued connections
-
[quote author="Santosh Reddy" date="1361345906"]Yes it will not work for queued connections[/quote]
It will not only not work, it will cause undefined behaviour and most likely a crash. IMO, that is a very good reason to recommend against this practice. Again: I must stress that as a developer of this particular piece of code, you have no control over how this signal will be connected to.
If you must pass a pointer, consider passing a QSharedPointer instead:
@
QSharedPointer<SignalOneArgument> arg = QSharedPointer<SignalOneArgument>(new SignalOneArgument());
emit eventToSignal(arg);
// don't delete manually, it will happen automatically when needed.
@