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. Proper way to specify slot arguments
Forum Update on Monday, May 27th 2025

Proper way to specify slot arguments

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 3 Posters 1.1k 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.
  • D Offline
    D Offline
    DRoscoe
    wrote on last edited by
    #1

    Let's say I am implementing a socket communication class that sends a QString to a remote host. In a typical C++ implementation without Qt, I would call the method as follows:

    QString some_message("Hello World");
    socket_class->sendData(some_message);
    

    The prototype for that method would be:

    void sendData(const QString& msg_out);
    

    This works fine in a single-threaded application. If the socket class were running on a separate thread, I would have to change the prototype to pass by value, rather than by reference. What I am confused about is the Qt Object model in this regard. If I were to implement the same in Qt with an event loop, I would define a signal and call:

    QString some_message("Hello World");
    emit sendMessage(some_message);
    

    Which would execute the slot sendData(). If the class were on the same thread as the main application, the pass by reference works as expected since the slot is executed immediately. However, if the socket code were on a separate thread, the pass by reference prototype still works. I am unclear why, and it leads me to ask what the best practice is for prototyping slots and their arguments.

    kshegunovK raven-worxR 2 Replies Last reply
    0
    • D DRoscoe

      Let's say I am implementing a socket communication class that sends a QString to a remote host. In a typical C++ implementation without Qt, I would call the method as follows:

      QString some_message("Hello World");
      socket_class->sendData(some_message);
      

      The prototype for that method would be:

      void sendData(const QString& msg_out);
      

      This works fine in a single-threaded application. If the socket class were running on a separate thread, I would have to change the prototype to pass by value, rather than by reference. What I am confused about is the Qt Object model in this regard. If I were to implement the same in Qt with an event loop, I would define a signal and call:

      QString some_message("Hello World");
      emit sendMessage(some_message);
      

      Which would execute the slot sendData(). If the class were on the same thread as the main application, the pass by reference works as expected since the slot is executed immediately. However, if the socket code were on a separate thread, the pass by reference prototype still works. I am unclear why, and it leads me to ask what the best practice is for prototyping slots and their arguments.

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

      @DRoscoe said in Proper way to specify slot arguments:

      However, if the socket code were on a separate thread, the pass by reference prototype still works. I am unclear why, and it leads me to ask what the best practice is for prototyping slots and their arguments.

      Always prefer pass by reference.
      As to why it works: Qt will make a shallow copy of the string (it's implicitly shared) when it packs the arguments for the deferred call and ultimately will put that copy in the event loop (for later execution of the slot) so you'd get a reference to that shallow copy, not to the original string.

      Kind regards.

      Edit: Here's the relevant part of the source if you're interested.

      Read and abide by the Qt Code of Conduct

      D 1 Reply Last reply
      3
      • D DRoscoe

        Let's say I am implementing a socket communication class that sends a QString to a remote host. In a typical C++ implementation without Qt, I would call the method as follows:

        QString some_message("Hello World");
        socket_class->sendData(some_message);
        

        The prototype for that method would be:

        void sendData(const QString& msg_out);
        

        This works fine in a single-threaded application. If the socket class were running on a separate thread, I would have to change the prototype to pass by value, rather than by reference. What I am confused about is the Qt Object model in this regard. If I were to implement the same in Qt with an event loop, I would define a signal and call:

        QString some_message("Hello World");
        emit sendMessage(some_message);
        

        Which would execute the slot sendData(). If the class were on the same thread as the main application, the pass by reference works as expected since the slot is executed immediately. However, if the socket code were on a separate thread, the pass by reference prototype still works. I am unclear why, and it leads me to ask what the best practice is for prototyping slots and their arguments.

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by raven-worx
        #3

        @DRoscoe said in Proper way to specify slot arguments:

        I am unclear why, and it leads me to ask what the best practice is for prototyping slots and their arguments.

        it works because Qt does all the work for you implicitly.
        Only registered meta types can be sent to another thread (using moc = signals, etc.)
        The precondition for a registered meta-type is that it has a public default constructor, a public copy constructor and a public destructor. This ensures that Qt can create copies and send them to the other thread.

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        D 1 Reply Last reply
        4
        • kshegunovK kshegunov

          @DRoscoe said in Proper way to specify slot arguments:

          However, if the socket code were on a separate thread, the pass by reference prototype still works. I am unclear why, and it leads me to ask what the best practice is for prototyping slots and their arguments.

          Always prefer pass by reference.
          As to why it works: Qt will make a shallow copy of the string (it's implicitly shared) when it packs the arguments for the deferred call and ultimately will put that copy in the event loop (for later execution of the slot) so you'd get a reference to that shallow copy, not to the original string.

          Kind regards.

          Edit: Here's the relevant part of the source if you're interested.

          D Offline
          D Offline
          DRoscoe
          wrote on last edited by
          #4

          @kshegunov that link is excellent. Thanks for that! A follow up question...

          If Qt uses implicit sharing and I should prefer passing by reference, does passing by value still invoke implicit sharing or is that bypassed, causing a deep copy to be created?

          kshegunovK 1 Reply Last reply
          0
          • raven-worxR raven-worx

            @DRoscoe said in Proper way to specify slot arguments:

            I am unclear why, and it leads me to ask what the best practice is for prototyping slots and their arguments.

            it works because Qt does all the work for you implicitly.
            Only registered meta types can be sent to another thread (using moc = signals, etc.)
            The precondition for a registered meta-type is that it has a public default constructor, a public copy constructor and a public destructor. This ensures that Qt can create copies and send them to the other thread.

            D Offline
            D Offline
            DRoscoe
            wrote on last edited by
            #5

            @raven-worx Thank you. That link is also an excellent resource.

            1 Reply Last reply
            0
            • D DRoscoe

              @kshegunov that link is excellent. Thanks for that! A follow up question...

              If Qt uses implicit sharing and I should prefer passing by reference, does passing by value still invoke implicit sharing or is that bypassed, causing a deep copy to be created?

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

              @DRoscoe said in Proper way to specify slot arguments:

              If Qt uses implicit sharing and I should prefer passing by reference, does passing by value still invoke implicit sharing or is that bypassed, causing a deep copy to be created?

              If the class is implicitly shared and you pass by value you'd get a shallow copy of the object that stays in the event loop. Whether that's detached (deep copied) depends on the methods you call on it. If you call immutable functions (const methods) no detach will take place. If you however call a regular (non-const) method, then the data will be copied (i.e. a deep copy will be done).

              Edit: A typical example why you should prefer const references (or at least const object) is if you have a vector in your slot which you only intend to iterate, e.g.:

              void MyClass::mySlot(QVector<int> v)
              {
                  QVector<int>::Iterator i = v.begin(), end = v.end(); //< Here you will cause a detach (data copy) to happen, because it will call the non-const begin() overload.
              }
              

              If you pass the vector as a const QVector<int> & (or const) then there's no needless data duplication.

              Read and abide by the Qt Code of Conduct

              D 1 Reply Last reply
              2
              • kshegunovK kshegunov

                @DRoscoe said in Proper way to specify slot arguments:

                If Qt uses implicit sharing and I should prefer passing by reference, does passing by value still invoke implicit sharing or is that bypassed, causing a deep copy to be created?

                If the class is implicitly shared and you pass by value you'd get a shallow copy of the object that stays in the event loop. Whether that's detached (deep copied) depends on the methods you call on it. If you call immutable functions (const methods) no detach will take place. If you however call a regular (non-const) method, then the data will be copied (i.e. a deep copy will be done).

                Edit: A typical example why you should prefer const references (or at least const object) is if you have a vector in your slot which you only intend to iterate, e.g.:

                void MyClass::mySlot(QVector<int> v)
                {
                    QVector<int>::Iterator i = v.begin(), end = v.end(); //< Here you will cause a detach (data copy) to happen, because it will call the non-const begin() overload.
                }
                

                If you pass the vector as a const QVector<int> & (or const) then there's no needless data duplication.

                D Offline
                D Offline
                DRoscoe
                wrote on last edited by
                #7

                @kshegunov Thanks!

                kshegunovK 1 Reply Last reply
                0
                • D DRoscoe

                  @kshegunov Thanks!

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

                  You're welcome!

                  Read and abide by the Qt Code of Conduct

                  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