[Interest] Qt signals and polymorphism

Bob Hood bhood2 at comcast.net
Sun Nov 22 18:21:45 CET 2015


I successfully addressed my QMutex/QWaitCondition breakage by refactoring my 
termination chain.  By sending a 'last call' down my class hierarchy, I was 
able to give the threads the time they needed to actually end gracefully, and 
release their resources.

However, while implementing this, I did discover that Qt signals cannot be 
virtualized, and I wanted to just confirm that in certain circumstances (mine 
in particular), they can actually mess with OOD.  Let me explain.

Given a class Channel:

     class Channel : public QObject
     {
     ...
         Channel();

     signals:
         void signal_channel_clear();
     ...
     }

and given a class Client that contains a class Channel:

     class Client : public QObject
     {
     ...
         Client(QSharedPointer<Channel> channel_pointer);

     signals:
         void signal_client_clear();

     protected slots:
         void slot_channel_clear();  // to receive Channel::signal_channel_clear
     ...
     }

then given a subclass of Channel:

     class SubChannel : public Channel
     {
     ...
         SubChannel();

     signals:
         void signal_channel_clear();
     ...
     }

If I connect Channel::signal_channel_clear() to Client::slot_channel_clear() 
when Client is passed a Channel pointer of type SubChannel:

     connect(channel_pointer.data(), &Channel::signal_channel_clear, this, 
&Client::slot_channel_clear);

then Client will never receive the signal when it is emitted from the 
SubChannel class (because it was bound to Channel::signal_channel_clear).  
Instead, from what I can fathom, I have to either dynamically cast SubChannel 
within Client (very ugly, because Client doesn't know about SubChannel and may 
not even have access to its header), or I have to make the Client slot public, 
and at a level above them all, make the connections on their behalf, 
increasing the coupling level:

     QSharedPointer<SubChannel> subchannel = QSharedPointer(new SubChannel());
     QSharedPointer<Client> client = QSharedPointer(new Client(subchannel));
     connect(client.data(), &Client::slot_channel_clear, subchannel.data(), 
&SubChannel::signal_channel_clear);

Basically, then, I wanted to know if this was the proper/only way to achieve 
this, of if there was something obvious I'm overlooking?  Both approaches are 
somewhat ugly, but the latter is (for me) the lesser of the two evils.



More information about the Interest mailing list