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. Why does the const Object returned by QList::at() block access to instance methods?
QtWS25 Last Chance

Why does the const Object returned by QList::at() block access to instance methods?

Scheduled Pinned Locked Moved Solved General and Desktop
qlistconstclassobjectc++
8 Posts 3 Posters 2.4k 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.
  • oblivioncthO Offline
    oblivioncthO Offline
    oblivioncth
    wrote on last edited by
    #1

    Hi,

    This is probably somewhat a general C++ question but it does pertain to the use of QList.

    I have a class (I'll say CustomClassA) that contains a member QList<CustomClassB> mListofB, which has a corresponding getter "getBList()" that simply returns mListofB. CustomClassB is a child of CustomClassA

    I know at() returns a constant reference to the selected object in this list and is the fastest access method, while value() returns a non-constant instance, is slightly slower, and generates a instance of the class contained in the list of the provided index is out of bounds. I prefer to use at() to ensure I get runtime exceptions if there is an out of bounds issue.

    My issue is this following:

    I have a pointer to CustomClassA in MainWindow (though this occurs without the use of a pointer) called mBSCPtr. At some point I need to read a member variable within CustomClassB that is part of the mListofB list in my CustomClassA instance. So naturally I try this:

    mClassAInstance->getBList().at(i).getterWithinClassB();
    

    but after I finish typing "at(i)." the auto-completer doesn't show any of the functions within ClassB and only lets me access static constant variables within that class. If I manually complete the statement as above, there I get the following error:

    error: 'this' argument to member function 'getterWithinClassB()' has type 'const CustomClassA::CustomClassB', but function is not marked const
    

    if I do this instead:

    CustomClassB tempBInstance = mClassAInstance->getBList().at(i);
    int desiredValue = tempBInstance.getterWithinClassB();
    

    it works fine. This is alright, except that now I have created a copy of that QList<CustomClassB> that I don't want (unnecessary memory usage) since I just want a copy of one value that is a member within that list.

    I can also compile:

    mClassAInstance->getBList().value(i).getterWithinClassB();
    

    with no problems, but like I said I'd prefer to use .at() to enforce proper bounds and if I had to guess I'd say that value() temporarily makes a copy of the list entry before it hands off the value I actually want and then destroys that copy, which has the same issue as the above.

    Is there any way I can adapt this so that I am using "at()", not making unneeded copies, and am still able to access the instance functions of CustomClassB?

    I'm certain I'm being dumb and forgetting a fundamental in regards to const objects. Anyone care to refresh me?

    Qt 5.12.3 32bit Debug via MSVC
    Windows 10

    JKSHJ 1 Reply Last reply
    0
    • oblivioncthO oblivioncth

      Hi,

      This is probably somewhat a general C++ question but it does pertain to the use of QList.

      I have a class (I'll say CustomClassA) that contains a member QList<CustomClassB> mListofB, which has a corresponding getter "getBList()" that simply returns mListofB. CustomClassB is a child of CustomClassA

      I know at() returns a constant reference to the selected object in this list and is the fastest access method, while value() returns a non-constant instance, is slightly slower, and generates a instance of the class contained in the list of the provided index is out of bounds. I prefer to use at() to ensure I get runtime exceptions if there is an out of bounds issue.

      My issue is this following:

      I have a pointer to CustomClassA in MainWindow (though this occurs without the use of a pointer) called mBSCPtr. At some point I need to read a member variable within CustomClassB that is part of the mListofB list in my CustomClassA instance. So naturally I try this:

      mClassAInstance->getBList().at(i).getterWithinClassB();
      

      but after I finish typing "at(i)." the auto-completer doesn't show any of the functions within ClassB and only lets me access static constant variables within that class. If I manually complete the statement as above, there I get the following error:

      error: 'this' argument to member function 'getterWithinClassB()' has type 'const CustomClassA::CustomClassB', but function is not marked const
      

      if I do this instead:

      CustomClassB tempBInstance = mClassAInstance->getBList().at(i);
      int desiredValue = tempBInstance.getterWithinClassB();
      

      it works fine. This is alright, except that now I have created a copy of that QList<CustomClassB> that I don't want (unnecessary memory usage) since I just want a copy of one value that is a member within that list.

      I can also compile:

      mClassAInstance->getBList().value(i).getterWithinClassB();
      

      with no problems, but like I said I'd prefer to use .at() to enforce proper bounds and if I had to guess I'd say that value() temporarily makes a copy of the list entry before it hands off the value I actually want and then destroys that copy, which has the same issue as the above.

      Is there any way I can adapt this so that I am using "at()", not making unneeded copies, and am still able to access the instance functions of CustomClassB?

      I'm certain I'm being dumb and forgetting a fundamental in regards to const objects. Anyone care to refresh me?

      Qt 5.12.3 32bit Debug via MSVC
      Windows 10

      JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by JKSH
      #2

      @oblivioncth said in Why does the const Object returned by QList::at() block access to instance methods?:

      ....but function is not marked const
      

      Mark it const. MyReturnType CustomClassB::getterWithinClassB() const { ... }

      In general, all methods that don't modify the object should be marked const.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      5
      • oblivioncthO Offline
        oblivioncthO Offline
        oblivioncth
        wrote on last edited by oblivioncth
        #3

        Oh wow,

        I'm embarrassed to say that I didn't even know a function could be marked as constant, other than marking its return object with 'const', which is why the error confused me a bit.

        Very useful, totally makes sense now, and obviously fixes my issue. Definitely a habit I'll pick up right away. Many complain about this, but man does C++ have a lot of different ways to use keywords.

        Thanks a bunch.

        JKSHJ 1 Reply Last reply
        1
        • oblivioncthO oblivioncth

          Oh wow,

          I'm embarrassed to say that I didn't even know a function could be marked as constant, other than marking its return object with 'const', which is why the error confused me a bit.

          Very useful, totally makes sense now, and obviously fixes my issue. Definitely a habit I'll pick up right away. Many complain about this, but man does C++ have a lot of different ways to use keywords.

          Thanks a bunch.

          JKSHJ Offline
          JKSHJ Offline
          JKSH
          Moderators
          wrote on last edited by JKSH
          #4

          @oblivioncth No problem, this is how we learn and become experienced.

          Anyway, here's a pretty good article that explains all you need to know about consts: https://www.cprogramming.com/tutorial/const_correctness.html

          Happy coding!

          man does C++ have a lot of different ways to use keywords.

          You know it.

          As an exercise, make sure you understand the effect of each of the 4 consts below:

          MyClass {
          public:
              const int& myfunc(const MyOtherClass * const arg) const;
          };
          

          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

          1 Reply Last reply
          4
          • oblivioncthO Offline
            oblivioncthO Offline
            oblivioncth
            wrote on last edited by
            #5

            Hey, going above and beyond! Thanks again.

            I'm not completely ignorant in the ways of C++ though, I'm not 100% certain, but fairly confident that:

            Const 1) Ensures the returned value can't be modified, the use cases of which I'll admit I'm not really privy to. I know that its only really useful when dealing with user defined classes and returning by value (which is the case in your example) to prevent memory modification if desired. I do remember seeing something about this being somewhat obsolete in C++ 11 (or was it 17) and forward, though I'm not sure why.

            Const 2) The pointer argument "arg" in that class is for the type "const MyOtherClass", i.e. a pointer to a constant value (value cannot)

            Const 3) Marks the pointer "arg" itself as pointer, so that the pointer itself also cannot be modified)

            Const 4) Thanks to you, I now understand this means that the function does not modify the object instance that the function is being called on/from (i.e. cannot manipulate member variables).

            Btw I do like a lot of the explanations on that site as they provide a lot of detail and examples, and I had never read the article for const.

            jsulmJ JKSHJ 2 Replies Last reply
            0
            • oblivioncthO oblivioncth

              Hey, going above and beyond! Thanks again.

              I'm not completely ignorant in the ways of C++ though, I'm not 100% certain, but fairly confident that:

              Const 1) Ensures the returned value can't be modified, the use cases of which I'll admit I'm not really privy to. I know that its only really useful when dealing with user defined classes and returning by value (which is the case in your example) to prevent memory modification if desired. I do remember seeing something about this being somewhat obsolete in C++ 11 (or was it 17) and forward, though I'm not sure why.

              Const 2) The pointer argument "arg" in that class is for the type "const MyOtherClass", i.e. a pointer to a constant value (value cannot)

              Const 3) Marks the pointer "arg" itself as pointer, so that the pointer itself also cannot be modified)

              Const 4) Thanks to you, I now understand this means that the function does not modify the object instance that the function is being called on/from (i.e. cannot manipulate member variables).

              Btw I do like a lot of the explanations on that site as they provide a lot of detail and examples, and I had never read the article for const.

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

              @oblivioncth said in Why does the const Object returned by QList::at() block access to instance methods?:

              when dealing with user defined classes and returning by value (which is the case in your example)

              It's not the case. Return value is here a reference. Const does not make any sense in case of return by value as a copy is returned and the original variable can't be changed this way. In case of a reference the original member variable can be changed if not marked as const.

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

              oblivioncthO 1 Reply Last reply
              2
              • jsulmJ jsulm

                @oblivioncth said in Why does the const Object returned by QList::at() block access to instance methods?:

                when dealing with user defined classes and returning by value (which is the case in your example)

                It's not the case. Return value is here a reference. Const does not make any sense in case of return by value as a copy is returned and the original variable can't be changed this way. In case of a reference the original member variable can be changed if not marked as const.

                oblivioncthO Offline
                oblivioncthO Offline
                oblivioncth
                wrote on last edited by oblivioncth
                #7

                @jsulm said in Why does the const Object returned by QList::at() block access to instance methods?:

                @oblivioncth said in Why does the const Object returned by QList::at() block access to instance methods?:

                when dealing with user defined classes and returning by value (which is the case in your example)

                It's not the case. Return value is here a reference. Const does not make any sense in case of return by value as a copy is returned and the original variable can't be changed this way. In case of a reference the original member variable can be changed if not marked as const.

                If you believe me that was actually just a typo. I meant to say return by reference (hence the "unless" since returning by value is typically the default choice), and as you said using a const on a return by value since that data cannot be modified anyway since you are only left with a copy in the end.

                1 Reply Last reply
                0
                • oblivioncthO oblivioncth

                  Hey, going above and beyond! Thanks again.

                  I'm not completely ignorant in the ways of C++ though, I'm not 100% certain, but fairly confident that:

                  Const 1) Ensures the returned value can't be modified, the use cases of which I'll admit I'm not really privy to. I know that its only really useful when dealing with user defined classes and returning by value (which is the case in your example) to prevent memory modification if desired. I do remember seeing something about this being somewhat obsolete in C++ 11 (or was it 17) and forward, though I'm not sure why.

                  Const 2) The pointer argument "arg" in that class is for the type "const MyOtherClass", i.e. a pointer to a constant value (value cannot)

                  Const 3) Marks the pointer "arg" itself as pointer, so that the pointer itself also cannot be modified)

                  Const 4) Thanks to you, I now understand this means that the function does not modify the object instance that the function is being called on/from (i.e. cannot manipulate member variables).

                  Btw I do like a lot of the explanations on that site as they provide a lot of detail and examples, and I had never read the article for const.

                  JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by
                  #8

                  @oblivioncth said in Why does the const Object returned by QList::at() block access to instance methods?:

                  Hey, going above and beyond! Thanks again.

                  You're most welcome!

                  I'm not completely ignorant in the ways of C++ though, I'm not 100% certain, but fairly confident that:

                  Const 1) Ensures the returned value can't be modified,

                  Yep.

                  the use cases of which I'll admit I'm not really privy to.

                  Use case 1:

                  • Allow the caller to read the data without creating a copy, AND
                  • Make sure the data is read-only

                  If the returned reference is non-const, the caller will be able to directly modify the object's internal memory. This breaks encapsulation.

                  Use case 2: Allow the function to be called in another const function.

                  There's a const and a non-const version of QList::operator[](int):

                  1. T & operator[](int i)
                  2. const T & operator[](int i) const

                  Version #1 allows the caller to modify the QList element. However, it cannot be called in a const function -- it will cause the error in your original post. Thus, version #2 is required for use in const functions.

                  I know that its only really useful when dealing with user defined classes and returning by value reference (which is the case in your example) to prevent memory modification if desired.

                  (Acknowledging your typo)

                  Why would it be "only really useful when dealing with user defined classes"? Notice that QList::at() returns a const reference.

                  I do remember seeing something about this being somewhat obsolete in C++ 11 (or was it 17) and forward, though I'm not sure why.

                  Returning const references is defintiely not obsolete.

                  You might be remembering move semantics, which is said to make passing parameters by const-reference obsolete: https://stackoverflow.com/questions/10231349/are-the-days-of-passing-const-stdstring-as-a-parameter-over

                  Qt will not be making this change anytime soon though; this is too disruptive.

                  Const 2) The pointer argument "arg" in that class is for the type "const MyOtherClass", i.e. a pointer to a constant value (value cannot)

                  Yep, myfunc() cannot modify the MyOtherClass object. (In other words, it can only call const methods of the object)

                  Const 3) Marks the pointer "arg" itself as pointer, so that the pointer itself also cannot be modified)

                  Yep. This is not very useful IMHO, but it's part of the language.

                  Const 4) Thanks to you, I now understand this means that the function does not modify the object instance that the function is being called on/from (i.e. cannot manipulate member variables).

                  Great!

                  Next, start thinking about the difference between logical const-ness and physical const-ness: https://isocpp.org/wiki/faq/const-correctness#logical-vs-physical-state

                  Btw I do like a lot of the explanations on that site as they provide a lot of detail and examples, and I had never read the article for const.

                  Agreed

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  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