Why I can’t call a virtual function from the Qt base class slot

Can someone explain to me why the overridden method is not called in the base class slot, instead I have the base version of the method:

class ThreadsDispatcher : public QObject { Q_OBJECT public: explicit ThreadsDispatcher(QObject *parent = 0); virtual ~ThreadsDispatcher(); virtual void OnThreadFinished(IThreadable *pWorker); public slots: void slotThreadFinished(IThreadable *pWorker); }; void ThreadsDispatcher::slotThreadFinished(IThreadable *pWorker) { OnThreadFinished(pWorker); } void ThreadsDispatcher::OnThreadFinished(IThreadable *pWorker) { qDebug << "Base method, class" << this->metaObject()->className(); } 

Subclass:

 class CommandsQueueDispatcher : public ThreadsDispatcher { Q_OBJECT public: explicit CommandsQueueDispatcher(CommandFactory* baseFactory, QObject *parent = 0); ~CommandsQueueDispatcher(); void OnThreadFinished(IThreadable *pWorker); }; void CommandsQueueDispatcher::OnThreadFinished(IThreadable *pWorker) { qDebug << "Subclass method, class" << this->metaObject()->className(); } 

After calling OnThreadFinished in the slot, I get:

 Base method, class ThreadsDispatcher 

If I call the OnThreadFinished method from another method, I become normal:

 Subclass method, class CommandsQueueDispatcher 

I tried connecting in the base class and subclass, but there were no changes:

 connect(pThreadWorker, SIGNAL(sigFinished(IThreadable*)), this, SLOT(slotThreadFinished(IThreadable*))); 

But if I connect from another class, that is, neither a subclass, nor a base class:

  connect(pThreadWorker, SIGNAL(sigFinished(IThreadable*)), pWorker, SLOT(slotThreadFinished(IThreadable*))); 

where I need to replace this with ptr variable, I get a normal result.

Function in which I connect:

 bool ThreadsDispatcher::AddThread(IThreadable* pThreadWorker) { connect(pThreadWorker, SIGNAL(sigFinished(IThreadable*)), this, SLOT(slotThreadFinished(IThreadable*))); } 

I do not create ThreadsDispatcher directly. I create a CommandsQueueDispatcher object non-static.

+4
source share
1 answer

Troubleshooting recommendation (too long for comment):

Try changing the slot like this:

 void ThreadsDispatcher::OnThreadFinished(IThreadable *pWorker) { qDebug << "Base method, class" << this->metaObject()->className(); } 

And the same goes for the derived class. See what is displayed.

If the output is “correct” in the sense that the virtual method matches the class name, then I suspect that you have an object of a base class, not an object of a derived class.

If there is an output mismatch, the virtual method of the base class does the printing, but displays the name of the derived class, I would look for any funny compiler flags and try to create SSCCE with a new project, then maybe ask again here and / or send an error report to Qt.

A link to start reading about this in the Qt docs.


Troubleshooting step-by-step: change the base class to abstract, making this method an absorber in the base class:

  virtual void OnThreadFinished(IThreadable *pWorker) = 0; 

... and then remove the define method. Now the compiler should tell you where you are trying to instantiate the base class.


Another suggestion: the basics of building Qt, listed, for example, in this answer . In particular, ensure that QObject subclasses are defined in the .h files that are listed in the list of .pro files of the HEADERS files.

0
source

Source: https://habr.com/ru/post/1501403/


All Articles