Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Pure virtual function called!
Forum Updated to NodeBB v4.3 + New Features

Pure virtual function called!

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 4 Posters 2.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SPlattenS Offline
    SPlattenS Offline
    SPlatten
    wrote on last edited by SPlatten
    #1

    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?

    Kind Regards,
    Sy

    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #4

      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?

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      SPlattenS 1 Reply Last reply
      4
      • O Offline
        O Offline
        ollarch
        wrote on last edited by ollarch
        #2

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

        SPlattenS 1 Reply Last reply
        7
        • O ollarch

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

          SPlattenS Offline
          SPlattenS Offline
          SPlatten
          wrote on last edited by
          #3

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

          Kind Regards,
          Sy

          jsulmJ 1 Reply Last reply
          -1
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #4

            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?

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            SPlattenS 1 Reply Last reply
            4
            • SPlattenS SPlatten

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

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #5

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

              void moduleThreadBody() override;
              

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              1
              • Christian EhrlicherC Christian Ehrlicher

                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?

                SPlattenS Offline
                SPlattenS Offline
                SPlatten
                wrote on last edited by
                #6

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

                Kind Regards,
                Sy

                1 Reply Last reply
                0
                • Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #7

                  You really should take some time to learn thread programming and esp. what join() does...

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  2
                  • O Offline
                    O Offline
                    ollarch
                    wrote on last edited by
                    #8

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

                    1 Reply Last reply
                    2

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved