Pure virtual function called!
-
I have a base class:
class clsModHelper : public QTcpSocket { Q_OBJECT public: virtual void moduleThreadBody() = 0; protected: bool mblnExit; QDataStream mdsIn; std::thread* mpThread; ... }
In the implementation of the constructor for this class:
clsModHelper::clsModHelper(QObject* pParent, int intArgc, char* parystrArgv[] ,const char* cpszTitle, double dblVersion) : QTcpSocket(pParent) , mblnExit(false) , mpThread(nullptr) { ... mpThread = new std::thread(&clsModHelper::threadBody, this); if ( mpThread != nullptr ) { //Ensure this thread is joined to the application module mpThread->join(); } } void clsModHelper::threadBody() { while( mblnExit == false ) { this->moduleThreadBody(); } delete mpThread; mpThread = nullptr; }
I have a another class which derived from this:
class clsModFileIO : public clsModHelper { public: void moduleThreadBody(); ... }
Implementation of constructor:
clsModFileIO::clsModFileIO(QObject* pParent, int intArgc, char* parystrArgv[]) : clsModHelper(pParent, intArgc, parystrArgv, "mdFileIO", 1.00) { }
This all compiles with no warnings or errors, however when I launch I am getting:
libc++abi.dylib: Pure virtual function called!
Displayed in the "Application Output", using the debugger I can see that the moduleThreadBody is not being called from the derived class, I've googled online and this is apparently a problem when calling from a base class constructor, but I'm not...the thread is created in the base class, is this the issue?
-
First: use 'override' keyword to be sure to really overwrite a function
Second: don't call the thread in the ctor since then the derived class is not yet instantiated
Third: why do you call join directly after creating the thread - why do you use a thread at all then? -
@SPlatten said in Pure virtual function called!:
clsModHelper
Hi, your class "clsModHelper" defines the method "moduleThreadBody" as private and it is why the inherited class "clsModFileIO" is not overriding it. It should be "protected" to let the derived class override it.
Another way to check if the override definition is ok is to use the keyword "override" into derived class:void moduleThreadBody() override;
This will be checked by the compiler avoiding runtime errors.
-
First: use 'override' keyword to be sure to really overwrite a function
Second: don't call the thread in the ctor since then the derived class is not yet instantiated
Third: why do you call join directly after creating the thread - why do you use a thread at all then? -
@Christian-Ehrlicher The purpose of the class is to add specific functionality that is not specific to this application but common to all instances that use it.
Its joined because I want the thread terminated when the application dies, not to hang up the main application.
-
You really should take some time to learn thread programming and esp. what
join()
does... -
@Christian-Ehrlicher said in Pure virtual function called!:
don't call the thread in the ctor since then the derived class is not yet instantiated
As @Christian-Ehrlicher said, you are calling the overrided method into constructor of the base class. Think on that when you create an object of the derived class, first the base part is initialized and finally the derived part, so the overrided method is not initialized yet.