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. Adding a virtual function causes strange result...
Forum Updated to NodeBB v4.3 + New Features

Adding a virtual function causes strange result...

Scheduled Pinned Locked Moved Solved General and Desktop
31 Posts 6 Posters 3.1k Views 2 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.
  • jsulmJ jsulm

    @SPlatten said in Adding a virtual function causes strange result...:

    clsXMLnode::strGetAttribute(QString)

    You should check what is happening there

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

    @jsulm , I didn't use the override keyword, should I?

    Kind Regards,
    Sy

    jsulmJ 1 Reply Last reply
    0
    • SPlattenS SPlatten

      @jsulm , this is where its called:

      QString clsScriptHelper::getValue(const QString& crstrID) {
          QString strValue;
          if ( crstrID.isEmpty() != true ) {
              clsXMLnode* pobjNode(clsXMLnode::spobjGetNodeById(crstrID));
              if ( pobjNode != nullptr ) {
                  clsXMLinterface* pobjXMLif(reinterpret_cast<clsXMLinterface*>(pobjNode));
                  if ( pobjXMLif != nullptr ) {
                      strValue = pobjXMLif->strGetData();
                  }
              }
      
          }
          return strValue;
      }
      

      The prototype for the above:

      Q_INVOKABLE QString getValue(const QString& crstrID);
      

      There is presently only one call to this, the only overridden instance is defined in the class clsQtLineEdit.

      Execution stops as I stated on the line I specified in the original post, how can I see if an error or exception has occurred because it isn't obvious.

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by J.Hilk
      #11

      @SPlatten said in Adding a virtual function causes strange result...:

      reinterpret_cast

      when using virtual inheritance !?!?!?

      use dynamic_cast or if QObject classes object_cast

      reinterpret_cast takes the raw pointer and considers it as being of the derived type. However, because of the virtual inheritance, a slight adjustment must be done to the pointer to point to the correct method dispatch table, and that's precisely what dynamic_cast will do.

      just as wrong, but probably wouldn't have resulted in a crash would be the use of static_cast.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      SPlattenS 1 Reply Last reply
      3
      • SPlattenS SPlatten

        @jsulm , this is where its called:

        QString clsScriptHelper::getValue(const QString& crstrID) {
            QString strValue;
            if ( crstrID.isEmpty() != true ) {
                clsXMLnode* pobjNode(clsXMLnode::spobjGetNodeById(crstrID));
                if ( pobjNode != nullptr ) {
                    clsXMLinterface* pobjXMLif(reinterpret_cast<clsXMLinterface*>(pobjNode));
                    if ( pobjXMLif != nullptr ) {
                        strValue = pobjXMLif->strGetData();
                    }
                }
        
            }
            return strValue;
        }
        

        The prototype for the above:

        Q_INVOKABLE QString getValue(const QString& crstrID);
        

        There is presently only one call to this, the only overridden instance is defined in the class clsQtLineEdit.

        Execution stops as I stated on the line I specified in the original post, how can I see if an error or exception has occurred because it isn't obvious.

        Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #12
        This post is deleted!
        1 Reply Last reply
        0
        • J.HilkJ J.Hilk

          @SPlatten said in Adding a virtual function causes strange result...:

          reinterpret_cast

          when using virtual inheritance !?!?!?

          use dynamic_cast or if QObject classes object_cast

          reinterpret_cast takes the raw pointer and considers it as being of the derived type. However, because of the virtual inheritance, a slight adjustment must be done to the pointer to point to the correct method dispatch table, and that's precisely what dynamic_cast will do.

          just as wrong, but probably wouldn't have resulted in a crash would be the use of static_cast.

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

          @J-Hilk said in Adding a virtual function causes strange result...:

          dynamic_cast

          I've replaced reinterpret_cast with dynamic_cast, same result.

          Kind Regards,
          Sy

          Christian EhrlicherC 1 Reply Last reply
          0
          • SPlattenS SPlatten

            @jsulm , I didn't use the override keyword, should I?

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

            @SPlatten said in Adding a virtual function causes strange result...:

            I didn't use the override keyword, should I?

            Yes you should. To ask the compiler to check whether you're really overriding virtual method. Can help to detect bugs at compile time.

            As I suggested: check what is happening in clsXMLnode::strGetAttribute(QString).
            My guess is that the strGetData() method from base class is called which returns an empty string, so the code then fails later.

            SPlattenS 1 Reply Last reply
            0
            • SPlattenS SPlatten

              @J-Hilk said in Adding a virtual function causes strange result...:

              dynamic_cast

              I've replaced reinterpret_cast with dynamic_cast, same result.

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #15

              @SPlatten said in Adding a virtual function causes strange result...:

              I've replaced reinterpret_cast with dynamic_cast, same result.

              For sure not.

              btw: dynamic_cast was proposed to your exact same problem some weeks ago already: https://forum.qt.io/topic/132420/how-to-access/4

              SPlattenS 1 Reply Last reply
              0
              • jsulmJ jsulm

                @SPlatten said in Adding a virtual function causes strange result...:

                I didn't use the override keyword, should I?

                Yes you should. To ask the compiler to check whether you're really overriding virtual method. Can help to detect bugs at compile time.

                As I suggested: check what is happening in clsXMLnode::strGetAttribute(QString).
                My guess is that the strGetData() method from base class is called which returns an empty string, so the code then fails later.

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

                @jsulm, I have a breakpoint on the first line of the function getValue, execution doesn't get as far as the breakpoint before the issue occurs.

                Kind Regards,
                Sy

                J.HilkJ jsulmJ 2 Replies Last reply
                0
                • Christian EhrlicherC Christian Ehrlicher

                  @SPlatten said in Adding a virtual function causes strange result...:

                  I've replaced reinterpret_cast with dynamic_cast, same result.

                  For sure not.

                  btw: dynamic_cast was proposed to your exact same problem some weeks ago already: https://forum.qt.io/topic/132420/how-to-access/4

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

                  @Christian-Ehrlicher That issue was resolved, this is new and dynamic_cast wasn't used to resolve the last issue, it was resolved with the suggested qobject_cast.

                  Kind Regards,
                  Sy

                  Christian EhrlicherC 1 Reply Last reply
                  0
                  • SPlattenS SPlatten

                    @jsulm, I have a breakpoint on the first line of the function getValue, execution doesn't get as far as the breakpoint before the issue occurs.

                    J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #18

                    @SPlatten your stack trace actually points to your clsXMLnode class.
                    clsXMLnode::strGetAttribute


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    kshegunovK 1 Reply Last reply
                    1
                    • SPlattenS SPlatten

                      @jsulm, I have a breakpoint on the first line of the function getValue, execution doesn't get as far as the breakpoint before the issue occurs.

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

                      @SPlatten I'm talking about clsXMLnode::strGetAttribute(QString).
                      If you check the stack trace you posted you will see that it is called shortly before the application stopps...

                      1 Reply Last reply
                      2
                      • SPlattenS SPlatten

                        @Christian-Ehrlicher That issue was resolved, this is new and dynamic_cast wasn't used to resolve the last issue, it was resolved with the suggested qobject_cast.

                        Christian EhrlicherC Offline
                        Christian EhrlicherC Offline
                        Christian Ehrlicher
                        Lifetime Qt Champion
                        wrote on last edited by
                        #20

                        @SPlatten said in Adding a virtual function causes strange result...:

                        it was resolved with the suggested qobject_cast.

                        Since your class is derived from QObject you can also use qobject_cast. Please learn the basics.

                        SPlattenS 1 Reply Last reply
                        1
                        • Christian EhrlicherC Christian Ehrlicher

                          @SPlatten said in Adding a virtual function causes strange result...:

                          it was resolved with the suggested qobject_cast.

                          Since your class is derived from QObject you can also use qobject_cast. Please learn the basics.

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

                          @Christian-Ehrlicher , I find your additions very insulting, I’ve been coding professionally since 1986.

                          Kind Regards,
                          Sy

                          JonBJ Christian EhrlicherC 2 Replies Last reply
                          0
                          • SPlattenS SPlatten

                            @Christian-Ehrlicher , I find your additions very insulting, I’ve been coding professionally since 1986.

                            JonBJ Online
                            JonBJ Online
                            JonB
                            wrote on last edited by JonB
                            #22

                            @SPlatten
                            I'm not sure what part of your code you think is implicated. I see:

                            1  QListData::size() const
                            2  QList<std::pair<QString, QString>>::length() const 
                            

                            and that is failing (according to your "the execution stops in qlist.h on line 115") on trying to get the length of the QList. Invalid QList at that point? That is what I see?

                            1 Reply Last reply
                            0
                            • SPlattenS SPlatten

                              @Christian-Ehrlicher , I find your additions very insulting, I’ve been coding professionally since 1986.

                              Christian EhrlicherC Offline
                              Christian EhrlicherC Offline
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on last edited by
                              #23

                              @SPlatten said in Adding a virtual function causes strange result...:

                              I’ve been coding professionally since 1986.

                              But not with c++ (at least I hope so) - when I want to learn a new language I normally start to learn the basics. But you ignore those basics in nearly every 'problem' you have and then wonder why people complain about the lack of the basics.

                              SPlattenS 1 Reply Last reply
                              1
                              • Christian EhrlicherC Christian Ehrlicher

                                @SPlatten said in Adding a virtual function causes strange result...:

                                I’ve been coding professionally since 1986.

                                But not with c++ (at least I hope so) - when I want to learn a new language I normally start to learn the basics. But you ignore those basics in nearly every 'problem' you have and then wonder why people complain about the lack of the basics.

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

                                @Christian-Ehrlicher that’s a huge assumption on your part.

                                Kind Regards,
                                Sy

                                1 Reply Last reply
                                0
                                • J.HilkJ J.Hilk

                                  @SPlatten your stack trace actually points to your clsXMLnode class.
                                  clsXMLnode::strGetAttribute

                                  kshegunovK Offline
                                  kshegunovK Offline
                                  kshegunov
                                  Moderators
                                  wrote on last edited by kshegunov
                                  #25

                                  @J-Hilk said in Adding a virtual function causes strange result...:

                                  @SPlatten your stack trace actually points to your clsXMLnode class.
                                  clsXMLnode::strGetAttribute

                                  If he reinterpret_casts it's going to point to that class and method since that's what to "reinterpret" means.

                                  @SPlatten said in Adding a virtual function causes strange result...:

                                  I've replaced reinterpret_cast with dynamic_cast, same result.

                                  You shouldn't use reinterpret_cast to begin with, as it's rather apparent you don't understand the implications of it; specifically to polymorphic calls and multiple inheritance. So while @Christian-Ehrlicher may seem brusque, you should do yourself a favor and listen to the advice.

                                  As for the issue at hand, you have called strGetAttribute on an invalid object, I'm reasonably certain. The reasons may vary, and reinterpret_casting incompatible types is one. Dangling pointers and uninitialized memory are other candidates. You need to sift through the debugger to find it. Out of curiosity where does clsQtLayout::addButton call clsXMLnode::strGetAttribute and where does clsXMLnode::setWidget call clsQtLayout::addButton - provide the relevant code around the calls.

                                  Read and abide by the Qt Code of Conduct

                                  SPlattenS 1 Reply Last reply
                                  3
                                  • kshegunovK kshegunov

                                    @J-Hilk said in Adding a virtual function causes strange result...:

                                    @SPlatten your stack trace actually points to your clsXMLnode class.
                                    clsXMLnode::strGetAttribute

                                    If he reinterpret_casts it's going to point to that class and method since that's what to "reinterpret" means.

                                    @SPlatten said in Adding a virtual function causes strange result...:

                                    I've replaced reinterpret_cast with dynamic_cast, same result.

                                    You shouldn't use reinterpret_cast to begin with, as it's rather apparent you don't understand the implications of it; specifically to polymorphic calls and multiple inheritance. So while @Christian-Ehrlicher may seem brusque, you should do yourself a favor and listen to the advice.

                                    As for the issue at hand, you have called strGetAttribute on an invalid object, I'm reasonably certain. The reasons may vary, and reinterpret_casting incompatible types is one. Dangling pointers and uninitialized memory are other candidates. You need to sift through the debugger to find it. Out of curiosity where does clsQtLayout::addButton call clsXMLnode::strGetAttribute and where does clsXMLnode::setWidget call clsQtLayout::addButton - provide the relevant code around the calls.

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

                                    @kshegunov , using the debugger I have a break point on the last if condition below:

                                    clsXMLinterface* pobjInterface(reinterpret_cast<clsXMLinterface*>(pobjButton));
                                    clsXMLnode* pobjNode(nullptr);
                                    if ( pobjInterface != nullptr ) {
                                        pobjNode = pobjInterface->pobjGetNode();
                                    }
                                    if ( pobjNode == nullptr ) {
                                        return;
                                    }
                                    

                                    pobjButton is a pointer to an instance of my derived class clsQtRadioButton:

                                        class clsQtRadioButton : public QRadioButton, public clsXMLinterface {
                                        Q_OBJECT
                                    

                                    pobjNode is returned as not null, pobjGetNode:

                                    clsXMLnode* pobjGetNode() { return mpobjNode; }
                                    

                                    I can see in the debugger the pobjInterface looks ok and mpobjNode is correct as I have assigned a human readable description to it:
                                    Screenshot 2021-12-22 at 07.41.17.png
                                    However pobjNode doesn't appear to be correct:
                                    Screenshot 2021-12-22 at 07.42.40.png
                                    And then trying to call strGetAttribute fails and causes the problem, but its because pobjNode isn't correct, why ?
                                    If I change the code to:

                                    clsQtRadioButton* pobjRadioBtn(qobject_cast<clsQtRadioButton*>(pobjButton));
                                    clsXMLnode* pobjNode(pobjRadioBtn->pobjGetNode());
                                    

                                    This way pobjNode is valid and there is no problem, however I need a polymorphic way to access pobjGetNode because there can be lots of different types of object derived from the same base class and I need the functionality to work for all of them.

                                    Kind Regards,
                                    Sy

                                    jsulmJ 1 Reply Last reply
                                    0
                                    • SPlattenS SPlatten

                                      @kshegunov , using the debugger I have a break point on the last if condition below:

                                      clsXMLinterface* pobjInterface(reinterpret_cast<clsXMLinterface*>(pobjButton));
                                      clsXMLnode* pobjNode(nullptr);
                                      if ( pobjInterface != nullptr ) {
                                          pobjNode = pobjInterface->pobjGetNode();
                                      }
                                      if ( pobjNode == nullptr ) {
                                          return;
                                      }
                                      

                                      pobjButton is a pointer to an instance of my derived class clsQtRadioButton:

                                          class clsQtRadioButton : public QRadioButton, public clsXMLinterface {
                                          Q_OBJECT
                                      

                                      pobjNode is returned as not null, pobjGetNode:

                                      clsXMLnode* pobjGetNode() { return mpobjNode; }
                                      

                                      I can see in the debugger the pobjInterface looks ok and mpobjNode is correct as I have assigned a human readable description to it:
                                      Screenshot 2021-12-22 at 07.41.17.png
                                      However pobjNode doesn't appear to be correct:
                                      Screenshot 2021-12-22 at 07.42.40.png
                                      And then trying to call strGetAttribute fails and causes the problem, but its because pobjNode isn't correct, why ?
                                      If I change the code to:

                                      clsQtRadioButton* pobjRadioBtn(qobject_cast<clsQtRadioButton*>(pobjButton));
                                      clsXMLnode* pobjNode(pobjRadioBtn->pobjGetNode());
                                      

                                      This way pobjNode is valid and there is no problem, however I need a polymorphic way to access pobjGetNode because there can be lots of different types of object derived from the same base class and I need the functionality to work for all of them.

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

                                      @SPlatten said in Adding a virtual function causes strange result...:

                                      why ?

                                      We do not know whether and how you're initialising it...

                                      "pobjNode is returned as not null" - doesn't mean it was initialised. You should initialise your pointers with nullptr before they are assigned proper pointers, else they can contain garbage.

                                      SPlattenS 1 Reply Last reply
                                      0
                                      • jsulmJ jsulm

                                        @SPlatten said in Adding a virtual function causes strange result...:

                                        why ?

                                        We do not know whether and how you're initialising it...

                                        "pobjNode is returned as not null" - doesn't mean it was initialised. You should initialise your pointers with nullptr before they are assigned proper pointers, else they can contain garbage.

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

                                        @jsulm , here is the constructor for the class clsXMLinterface:

                                        clsXMLinterface::clsXMLinterface(clsXMLnode* pobjNode) : mpobjNode(pobjNode) {
                                        

                                        And clsQtRadioButton:

                                        clsQtRadioButton::clsQtRadioButton(clsXMLnode* pobjNode, QString* pstrCSS
                                                                                               , QWidget* pParent)
                                                                    : QRadioButton(pParent), clsXMLinterface(pobjNode) {
                                        

                                        The formatting of this constructor is common to all instances. Widgets like instances of clsQtRadioButton are created by another call:

                                                    pobjWidget = qobject_cast<QWidget*>(clsCNT::pCreate(this,
                                                                                                        mstrName,
                                                                                                        strCSS,
                                                                                                        slstProperties,
                                                                                                        pobjParWidget));
                                        

                                        clsCNT::pCreate:

                                        QWidget* clsCNT::pCreate(clsXMLnode* pobjNode, const QString& crstrType
                                                                ,QString& rstrCSS, QStringList& rslstProperties
                                                                ,QWidget* pobjParent) {
                                            QWidget* pobjWidget(nullptr);    
                                            if ( pobjNode != nullptr ) {
                                                if ( crstrType.compare(clsCNT::mscszButton) == 0 ) {
                                                    pobjWidget = new clsQtPushBtn(pobjNode, &rstrCSS, pobjParent);
                                        

                                        The above is just a sample, pobjNode is passed by pCreate as this.

                                        Kind Regards,
                                        Sy

                                        jsulmJ 1 Reply Last reply
                                        0
                                        • SPlattenS SPlatten

                                          @jsulm , here is the constructor for the class clsXMLinterface:

                                          clsXMLinterface::clsXMLinterface(clsXMLnode* pobjNode) : mpobjNode(pobjNode) {
                                          

                                          And clsQtRadioButton:

                                          clsQtRadioButton::clsQtRadioButton(clsXMLnode* pobjNode, QString* pstrCSS
                                                                                                 , QWidget* pParent)
                                                                      : QRadioButton(pParent), clsXMLinterface(pobjNode) {
                                          

                                          The formatting of this constructor is common to all instances. Widgets like instances of clsQtRadioButton are created by another call:

                                                      pobjWidget = qobject_cast<QWidget*>(clsCNT::pCreate(this,
                                                                                                          mstrName,
                                                                                                          strCSS,
                                                                                                          slstProperties,
                                                                                                          pobjParWidget));
                                          

                                          clsCNT::pCreate:

                                          QWidget* clsCNT::pCreate(clsXMLnode* pobjNode, const QString& crstrType
                                                                  ,QString& rstrCSS, QStringList& rslstProperties
                                                                  ,QWidget* pobjParent) {
                                              QWidget* pobjWidget(nullptr);    
                                              if ( pobjNode != nullptr ) {
                                                  if ( crstrType.compare(clsCNT::mscszButton) == 0 ) {
                                                      pobjWidget = new clsQtPushBtn(pobjNode, &rstrCSS, pobjParent);
                                          

                                          The above is just a sample, pobjNode is passed by pCreate as this.

                                          jsulmJ Offline
                                          jsulmJ Offline
                                          jsulm
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #29
                                          This post is deleted!
                                          SPlattenS 2 Replies Last reply
                                          0

                                          • Login

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