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!
QtWS25 Last Chance

Pure virtual function called!

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 4 Posters 2.3k Views
  • 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.
  • S Offline
    S Offline
    SPlatten
    wrote on 4 Nov 2020, 09:37 last edited by SPlatten 11 Apr 2020, 09:56
    #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
    • C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 4 Nov 2020, 10:00 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

      S 1 Reply Last reply 4 Nov 2020, 10:02
      4
      • O Offline
        O Offline
        ollarch
        wrote on 4 Nov 2020, 09:43 last edited by ollarch 11 Apr 2020, 09:52
        #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.

        S 1 Reply Last reply 4 Nov 2020, 09:56
        7
        • O ollarch
          4 Nov 2020, 09:43

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

          S Offline
          S Offline
          SPlatten
          wrote on 4 Nov 2020, 09:56 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

          J 1 Reply Last reply 4 Nov 2020, 10:00
          -1
          • C Offline
            C Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on 4 Nov 2020, 10:00 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

            S 1 Reply Last reply 4 Nov 2020, 10:02
            4
            • S SPlatten
              4 Nov 2020, 09:56

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

              J Offline
              J Offline
              jsulm
              Lifetime Qt Champion
              wrote on 4 Nov 2020, 10:00 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
              • C Christian Ehrlicher
                4 Nov 2020, 10:00

                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?

                S Offline
                S Offline
                SPlatten
                wrote on 4 Nov 2020, 10:02 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
                • C Offline
                  C Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on 4 Nov 2020, 10:04 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 4 Nov 2020, 10:05 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

                    8/8

                    4 Nov 2020, 10:05

                    • Login

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