Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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?


  • Lifetime Qt Champion

    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.



  • @ollarch , sorry its only private in the post here...in the actual code its public, I didn't want to post everything, I'll edit the post now.


  • Lifetime Qt Champion

    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?


  • Lifetime Qt Champion

    @SPlatten Change it like this in the derived class to make sure you're really overriding:

    void moduleThreadBody() override;
    


  • @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.


  • Lifetime Qt Champion

    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.


Log in to reply