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. generalize a c++ method
Qt 6.11 is out! See what's new in the release blog

generalize a c++ method

Scheduled Pinned Locked Moved Solved General and Desktop
34 Posts 5 Posters 13.6k 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.
  • ODБOïO ODБOï

    @mrjj do you mean like this ? this looks good except i will have a huge switch

      enum class UpdateHandlers: qint32{
            NINDEX = 0, 
            SPEED = 1,  
            XXX = 2
        };
    
    void MachineBackend::uaSub1(QScopedPointer<QOpcUaNode> &node, QString nodeId, UpdateHandlers theHandler){
        
        node.reset(m_client->node(nodeId));
        node->enableMonitoring(QOpcUa::NodeAttribute::Value, QOpcUaMonitoringParameters(200));
        QObject::connect(node.data(),&QOpcUaNode::attributeUpdated,[=](QOpcUa::NodeAttribute attr,const QVariant &value){
                  
            switch (theHandler) {
            
            case UpdateHandlers::NINDEX :   nIndexUpdated(attr,value);break;
            case UpdateHandlers::SPEED  :   nSpeeedUpdated(attr,value);break;
            case UpdateHandlers::XXX    :   xxxUpdated(attr,value);break;
            default: break;            
            }              
        });  
        
        return;    
    }
    
    
    
    
    ODБOïO Offline
    ODБOïO Offline
    ODБOï
    wrote on last edited by ODБOï
    #8

    edit @mrjj sorry not for you

    @jsulm
    do you mean this ?

     enum  UpdateHandlers : qint32{
            NINDEX, 
            SPEED, 
            XXX
        };
    
    
    void MachineBackend::uaSub1(QScopedPointer<QOpcUaNode> &node, QString nodeId, UpdateHandlers theHandler){
        
        node.reset(m_client->node(nodeId));
        node->enableMonitoring(QOpcUa::NodeAttribute::Value, QOpcUaMonitoringParameters(200));
        QObject::connect(node.data(),&QOpcUaNode::attributeUpdated,[=](QOpcUa::NodeAttribute attr,const QVariant &value){
           
            
            switch (theHandler) {
            
            case UpdateHandlers::NINDEX :   nIndexUpdated(attr,value);break;
            case UpdateHandlers::SPEED  :   nSpeeedUpdated(attr,value);break;
            case UpdateHandlers::XXX    :   xxxUpdated(attr,value);break;
            default: break;
                
            }
            
            
        });
        
        
        return;
        
    }
    
    1 Reply Last reply
    0
    • ODБOïO ODБOï

      @mrjj do you mean like this ? this looks good except i will have a huge switch

        enum class UpdateHandlers: qint32{
              NINDEX = 0, 
              SPEED = 1,  
              XXX = 2
          };
      
      void MachineBackend::uaSub1(QScopedPointer<QOpcUaNode> &node, QString nodeId, UpdateHandlers theHandler){
          
          node.reset(m_client->node(nodeId));
          node->enableMonitoring(QOpcUa::NodeAttribute::Value, QOpcUaMonitoringParameters(200));
          QObject::connect(node.data(),&QOpcUaNode::attributeUpdated,[=](QOpcUa::NodeAttribute attr,const QVariant &value){
                    
              switch (theHandler) {
              
              case UpdateHandlers::NINDEX :   nIndexUpdated(attr,value);break;
              case UpdateHandlers::SPEED  :   nSpeeedUpdated(attr,value);break;
              case UpdateHandlers::XXX    :   xxxUpdated(attr,value);break;
              default: break;            
              }              
          });  
          
          return;    
      }
      
      
      
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #9

      @LeLev See https://stackoverflow.com/questions/14315346/function-pointer-of-a-non-static-member-function-of-a-class
      With non-static methods you need an instance of the class to call the method:

      typedef void (T::*MethodPtr) ();
      MethodPtr method = &T::MethodA;
      T *obj = new T();
      obj->*method();
      
      ODБOïO 1 Reply Last reply
      1
      • jsulmJ jsulm

        @LeLev See https://stackoverflow.com/questions/14315346/function-pointer-of-a-non-static-member-function-of-a-class
        With non-static methods you need an instance of the class to call the method:

        typedef void (T::*MethodPtr) ();
        MethodPtr method = &T::MethodA;
        T *obj = new T();
        obj->*method();
        
        ODБOïO Offline
        ODБOïO Offline
        ODБOï
        wrote on last edited by
        #10

        @jsulm i think i can not use this last solution, because there is only one instance of this class. it is instantiated in the main.cpp and putted as contextProperty, it is never destroyed and has same life time as my application. I can not create another object of this class

        J.HilkJ jsulmJ 2 Replies Last reply
        0
        • ODБOïO ODБOï

          @jsulm i think i can not use this last solution, because there is only one instance of this class. it is instantiated in the main.cpp and putted as contextProperty, it is never destroyed and has same life time as my application. I can not create another object of this class

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

          @LeLev said in generalize a c++ method:

          @jsulm i think i can not use this last solution, because there is only one instance of this class. it is instantiated in the main.cpp and putted as contextProperty, it is never destroyed and has same life time as my application. I can not create another object of this class

          ok, when this - in essence - is a singleton, why don't you make the member variable then also static?


          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.

          ODБOïO 1 Reply Last reply
          1
          • ODБOïO Offline
            ODБOïO Offline
            ODБOï
            wrote on last edited by
            #12

            because i'm JS guy ... i 'm learning Qt/cpp only for 2 years now.
            let me try it

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

              @LeLev said in generalize a c++ method:

              @jsulm i think i can not use this last solution, because there is only one instance of this class. it is instantiated in the main.cpp and putted as contextProperty, it is never destroyed and has same life time as my application. I can not create another object of this class

              ok, when this - in essence - is a singleton, why don't you make the member variable then also static?

              ODБOïO Offline
              ODБOïO Offline
              ODБOï
              wrote on last edited by ODБOï
              #13

              @J-Hilk said in generalize a c++ method:

              why don't you make the member variable then also static?

              i have one member variable per subscription,
              each member variable has a Q_PROPERTY corresponding to it, so i can use the variable value from QML.

              is it possible do define Q_PROPERTIES for a static member variable ?

              Im trying but getting errors :
              moc_machinebackend.cpp:-1: erreur : undefined reference to `MachineBackend::m_url'

               Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged)
              
              public:
               QString url()const{
                     return MachineBackend::m_url; 
                  }
                  void setUrl(const QString nUrl){
                      if(MachineBackend::m_url==nUrl)return;
                      MachineBackend::m_url = nUrl;
                      emit urlChanged(nUrl);
                  }
              
              private : 
              static QString m_url;
              
              signals:
              void urlChanged(QString url);
              
              1 Reply Last reply
              0
              • ODБOïO ODБOï

                @jsulm i think i can not use this last solution, because there is only one instance of this class. it is instantiated in the main.cpp and putted as contextProperty, it is never destroyed and has same life time as my application. I can not create another object of this class

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

                @LeLev said in generalize a c++ method:

                i think i can not use this last solution

                Sure you can: you pass the pointer to second method when you call the first method, right? And since both methods are not static you call the first method already on an instance (which is "this" inside the method):

                this->*method(); // method is the pointer to the other method
                
                ODБOïO 1 Reply Last reply
                1
                • jsulmJ jsulm

                  @LeLev said in generalize a c++ method:

                  i think i can not use this last solution

                  Sure you can: you pass the pointer to second method when you call the first method, right? And since both methods are not static you call the first method already on an instance (which is "this" inside the method):

                  this->*method(); // method is the pointer to the other method
                  
                  ODБOïO Offline
                  ODБOïO Offline
                  ODБOï
                  wrote on last edited by ODБOï
                  #15

                  @jsulm said in generalize a c++ method:

                  : you pass the pointer to second method when you call the first method, right?

                  Yes, but it only works if the
                  2nd method is static !

                  //first 
                  void uaSub(QScopedPointer<QOpcUaNode> &node, QString nodeId , void (*theUpdateHandler)(QOpcUa::NodeAttribute attr,const QVariant &value)){...}
                  // 2nd
                  static void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
                  
                  
                  uaSub(nIndexNode,"ns=4;s=MAIN.nIndex",*nIndexUpdated){...}
                  
                  //Here **nIndexUpdated** must be static !  no ?
                  

                  if it is not static i get :
                  reference to non-static member function must be called error

                  jsulmJ 1 Reply Last reply
                  0
                  • ODБOïO ODБOï

                    @jsulm said in generalize a c++ method:

                    : you pass the pointer to second method when you call the first method, right?

                    Yes, but it only works if the
                    2nd method is static !

                    //first 
                    void uaSub(QScopedPointer<QOpcUaNode> &node, QString nodeId , void (*theUpdateHandler)(QOpcUa::NodeAttribute attr,const QVariant &value)){...}
                    // 2nd
                    static void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
                    
                    
                    uaSub(nIndexNode,"ns=4;s=MAIN.nIndex",*nIndexUpdated){...}
                    
                    //Here **nIndexUpdated** must be static !  no ?
                    

                    if it is not static i get :
                    reference to non-static member function must be called error

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

                    @LeLev Please take a closer look at the snippet I provided before:

                    typedef void (T::*MethodPtr) ();
                    MethodPtr method = &T::MethodA;
                    T *obj = new T();
                    obj->*method();
                    

                    Your syntax is not even correct as you have to use & to get a pointer not *
                    So in your case something like

                    class A
                    {
                        typedef void (A::*MethodPtr) ();
                        void nIndexUpdated() {}
                        void uaSub(..., MethodPtr ptr) {
                            this->*ptr();
                        }
                    
                        // Somewhere inside class A you call uaSub
                        uaSub(/*params*/, &A::nIndexUpdated);
                    }
                    
                    ODБOïO 1 Reply Last reply
                    1
                    • jsulmJ jsulm

                      @LeLev Please take a closer look at the snippet I provided before:

                      typedef void (T::*MethodPtr) ();
                      MethodPtr method = &T::MethodA;
                      T *obj = new T();
                      obj->*method();
                      

                      Your syntax is not even correct as you have to use & to get a pointer not *
                      So in your case something like

                      class A
                      {
                          typedef void (A::*MethodPtr) ();
                          void nIndexUpdated() {}
                          void uaSub(..., MethodPtr ptr) {
                              this->*ptr();
                          }
                      
                          // Somewhere inside class A you call uaSub
                          uaSub(/*params*/, &A::nIndexUpdated);
                      }
                      
                      ODБOïO Offline
                      ODБOïO Offline
                      ODБOï
                      wrote on last edited by ODБOï
                      #17

                      @jsulm
                      thank you so much for the help you provide.
                      Unfortunately i'm so bad, i can't make this work

                      class MachineBackend : public QObject
                      {
                          typedef void (MachineBackend::*MethodPtr) ();
                          Q_OBJECT
                      
                      void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
                      
                      void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                             
                             this->*updateHandlerPtr(); // < error here 
                      
                          }
                      };
                      

                      called object type 'MachineBackend ::MethodPtr' (aka 'void (MachineBackend ::*)()' ) is not a function or function pointer

                      jsulmJ 1 Reply Last reply
                      0
                      • ODБOïO ODБOï

                        @jsulm
                        thank you so much for the help you provide.
                        Unfortunately i'm so bad, i can't make this work

                        class MachineBackend : public QObject
                        {
                            typedef void (MachineBackend::*MethodPtr) ();
                            Q_OBJECT
                        
                        void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
                        
                        void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                               
                               this->*updateHandlerPtr(); // < error here 
                        
                            }
                        };
                        

                        called object type 'MachineBackend ::MethodPtr' (aka 'void (MachineBackend ::*)()' ) is not a function or function pointer

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

                        @LeLev Try

                        this->updateHandlerPtr();
                        
                        ODБOïO 1 Reply Last reply
                        1
                        • jsulmJ jsulm

                          @LeLev Try

                          this->updateHandlerPtr();
                          
                          ODБOïO Offline
                          ODБOïO Offline
                          ODБOï
                          wrote on last edited by
                          #19

                          @jsulm said in generalize a c++ method:

                          this->updateHandlerPtr();

                          yes i did also, in that case error is :

                          no member named 'updateHandlerPtr' in 'MachineBackend '
                          which is true

                          jsulmJ 1 Reply Last reply
                          0
                          • ODБOïO ODБOï

                            @jsulm said in generalize a c++ method:

                            this->updateHandlerPtr();

                            yes i did also, in that case error is :

                            no member named 'updateHandlerPtr' in 'MachineBackend '
                            which is true

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

                            @LeLev This should compile:

                            (this->*updateHandlerPtr)();
                            

                            Method pointers are a mess :-)

                            1 Reply Last reply
                            2
                            • ODБOïO Offline
                              ODБOïO Offline
                              ODБOï
                              wrote on last edited by
                              #21

                              yes now it doas. awesome ! thank you so much!

                              class MachineBackend : public QObject
                              {
                                  typedef void (MachineBackend::*MethodPtr) ();
                                  Q_OBJECT
                              
                              void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
                              
                              void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                                     
                                     (this->*updateHandlerPtr)();
                              
                                  }
                              };
                              
                              
                              
                              

                              there is still an issue in the usSub() call

                              //  Somewhere inside class
                                uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::nIndexUpdated);  // << error
                              //
                              

                              error : reference to non-static member function must be called

                              im trying every possible syntax right now ...

                              jsulmJ 2 Replies Last reply
                              0
                              • ODБOïO ODБOï

                                yes now it doas. awesome ! thank you so much!

                                class MachineBackend : public QObject
                                {
                                    typedef void (MachineBackend::*MethodPtr) ();
                                    Q_OBJECT
                                
                                void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
                                
                                void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                                       
                                       (this->*updateHandlerPtr)();
                                
                                    }
                                };
                                
                                
                                
                                

                                there is still an issue in the usSub() call

                                //  Somewhere inside class
                                  uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::nIndexUpdated);  // << error
                                //
                                

                                error : reference to non-static member function must be called

                                im trying every possible syntax right now ...

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

                                @LeLev said in generalize a c++ method:

                                uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::nIndexUpdated);

                                uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", &MachineBackend::nIndexUpdated);
                                
                                ODБOïO 1 Reply Last reply
                                1
                                • ODБOïO ODБOï

                                  yes now it doas. awesome ! thank you so much!

                                  class MachineBackend : public QObject
                                  {
                                      typedef void (MachineBackend::*MethodPtr) ();
                                      Q_OBJECT
                                  
                                  void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
                                  
                                  void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                                         
                                         (this->*updateHandlerPtr)();
                                  
                                      }
                                  };
                                  
                                  
                                  
                                  

                                  there is still an issue in the usSub() call

                                  //  Somewhere inside class
                                    uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::nIndexUpdated);  // << error
                                  //
                                  

                                  error : reference to non-static member function must be called

                                  im trying every possible syntax right now ...

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

                                  @LeLev This small example works for me:

                                  #include <iostream>
                                  
                                  class A
                                  {
                                  public:
                                      typedef void (A::*MethodPtr) ();
                                      void someMethod() { std::cout << "Hallo!" << std::endl; }
                                      void uaSub2(MethodPtr updateHandlerPtr){
                                         (this->* updateHandlerPtr)();
                                      }
                                  };
                                  
                                  int main()
                                  {
                                      A a;
                                      a.uaSub2(&A::someMethod); 
                                      return 0;
                                  }
                                  
                                  1 Reply Last reply
                                  1
                                  • jsulmJ jsulm

                                    @LeLev said in generalize a c++ method:

                                    uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::nIndexUpdated);

                                    uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", &MachineBackend::nIndexUpdated);
                                    
                                    ODБOïO Offline
                                    ODБOïO Offline
                                    ODБOï
                                    wrote on last edited by
                                    #24

                                    @jsulm yes sorry that is the first one i have tryed:

                                    uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", &MachineBackend::nIndexUpdated);
                                    
                                    // err :  cannot initialize a parameter of type 'Machinebackend::MethorPtr' (aka 'void (MAchinebackend::*)()') with an rvalue of type 'void (MAchineBAckend::*)(QOpcUa::NodeAttribute, const QVariant &)' : different number of parameters (0 vs 2)
                                    
                                    error : no matching function for call to 'MachineBackend::uaSub2(QScopedPointer<QOpcUaNode>&, const char [19], <unresolved overloaded function type>)'
                                             uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex",MachineBackend::nIndexUpdated);
                                                                                                                 ^
                                    
                                    jsulmJ 2 Replies Last reply
                                    0
                                    • ODБOïO ODБOï

                                      @jsulm yes sorry that is the first one i have tryed:

                                      uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", &MachineBackend::nIndexUpdated);
                                      
                                      // err :  cannot initialize a parameter of type 'Machinebackend::MethorPtr' (aka 'void (MAchinebackend::*)()') with an rvalue of type 'void (MAchineBAckend::*)(QOpcUa::NodeAttribute, const QVariant &)' : different number of parameters (0 vs 2)
                                      
                                      error : no matching function for call to 'MachineBackend::uaSub2(QScopedPointer<QOpcUaNode>&, const char [19], <unresolved overloaded function type>)'
                                               uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex",MachineBackend::nIndexUpdated);
                                                                                                                   ^
                                      
                                      jsulmJ Offline
                                      jsulmJ Offline
                                      jsulm
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #25
                                      This post is deleted!
                                      ODБOïO 1 Reply Last reply
                                      0
                                      • ODБOïO ODБOï

                                        @jsulm yes sorry that is the first one i have tryed:

                                        uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", &MachineBackend::nIndexUpdated);
                                        
                                        // err :  cannot initialize a parameter of type 'Machinebackend::MethorPtr' (aka 'void (MAchinebackend::*)()') with an rvalue of type 'void (MAchineBAckend::*)(QOpcUa::NodeAttribute, const QVariant &)' : different number of parameters (0 vs 2)
                                        
                                        error : no matching function for call to 'MachineBackend::uaSub2(QScopedPointer<QOpcUaNode>&, const char [19], <unresolved overloaded function type>)'
                                                 uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex",MachineBackend::nIndexUpdated);
                                                                                                                     ^
                                        
                                        jsulmJ Offline
                                        jsulmJ Offline
                                        jsulm
                                        Lifetime Qt Champion
                                        wrote on last edited by jsulm
                                        #26

                                        @LeLev said in generalize a c++ method:

                                        nIndexUpdated

                                        This one has parameters, you need to adapt your typedef for the pointer accordingly.
                                        This is what the error tells you.

                                        1 Reply Last reply
                                        1
                                        • jsulmJ jsulm

                                          This post is deleted!

                                          ODБOïO Offline
                                          ODБOïO Offline
                                          ODБOï
                                          wrote on last edited by
                                          #27

                                          @jsulm

                                          class MachineBackend : public QObject
                                          {
                                              typedef void (MachineBackend::*MethodPtr) ();
                                              Q_OBJECT
                                          
                                          void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
                                          
                                          void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                                                 
                                                 (this->*updateHandlerPtr)();
                                          
                                              }
                                          };
                                          

                                          in the constructor of this class i call m_client.connectToServer(), then connect stateChanged signal of the m_client to a method where i want to create the subscriptions :

                                           QObject::connect(m_client.data(), &QOpcUaClient::stateChanged, this, &MachineBackend::clientStateHandler);
                                          
                                          void MachineBackend::clientStateHandler(QOpcUaClient::ClientState state)
                                          {
                                              setConnected((state == QOpcUaClient::ClientState::Connected)); 
                                          
                                              if (state == QOpcUaClient::ClientState::Connected) {// if client is connected i create subscriptions
                                                           
                                                  // uaSub(nIndexNode,"ns=4;s=MAIN.nIndex",*nIndexUpdated); // function pointer to static function
                                          
                                                  // uaSub1(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::NINDEX) // enum
                                                  
                                                   uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex",&MachineBackend::nIndexUpdated);   
                                          
                                              }
                                          
                                             [...]
                                          }
                                          
                                          

                                          I think i have to adapt my typedef because &QOpcUaClient::stateChanged returns 2 parameters

                                          jsulmJ 1 Reply 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