why does const not work on pointed objects?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Corno

    why does const not work on pointed objects?

    Hi all,

    There's probably a good reason why a const object can call non const
    functions of the objects where it's member pointers point to.
    I just don't see it. For me, that makes the the const keyword a lot less
    usable.
    Can anybody tell me what that good reason is?

    TIA,

    Corno


  • Mike Wahler

    #2
    Re: why does const not work on pointed objects?


    "Corno" <corno@%spam%.d ds.nl> wrote in message
    news:c08qni$ki8 $1@reader08.wxs .nl...[color=blue]
    > Hi all,
    >
    > There's probably a good reason why a const object can call[/color]

    Objects cannot 'call' anything.
    Code inside a member function can indeed call other (member --
    either same class or other class--- or nonmember) functions,
    though. The constness of a different type object whose member
    function makes the call doesn't matter at all. That's probably
    incomprehensibl e, I know... :-)
    [color=blue]
    > non const
    > functions of the objects where it's member pointers point to.[/color]


    A nonconst member function object can be called only for nonconst objects.
    This 'protects' against inadvertent modification of a const object.

    A const member function can be called for either const or nonconst objects.
    [color=blue]
    > I just don't see it. For me, that makes the the const keyword a lot less
    > usable.[/color]

    I find it quite usable.
    [color=blue]
    > Can anybody tell me what that good reason is?[/color]

    I cannot give a reason for something which isn't true. :-)

    Perhaps you can demonstrate your questions more clear with some code?
    (with appropriate accompanying comments).

    -Mike


    Comment

    • Andrey Tarasevich

      #3
      Re: why does const not work on pointed objects?

      Corno wrote:[color=blue]
      > ...
      > There's probably a good reason why a const object can call non const
      > functions of the objects where it's member pointers point to.
      > I just don't see it. For me, that makes the the const keyword a lot less
      > usable.
      > Can anybody tell me what that good reason is?
      > ...[/color]

      Because you are dealing with two completely unrelated objects. Would you
      please clarify, why do you think that constness of one object (or of an
      access path to one object) should somehow implicate constness of a
      completely unrelated other object (or of an access path to other object)?

      --
      Best regards,
      Andrey Tarasevich

      Comment

      • John Carson

        #4
        Re: why does const not work on pointed objects?

        "Corno" <corno@%spam%.d ds.nl> wrote in message
        news:c08qni$ki8 $1@reader08.wxs .nl[color=blue]
        > Hi all,
        >
        > There's probably a good reason why a const object can call non const
        > functions of the objects where it's member pointers point to.
        > I just don't see it. For me, that makes the the const keyword a lot
        > less usable.
        > Can anybody tell me what that good reason is?
        >
        > TIA,
        >
        > Corno[/color]

        I suspect that you are confusing two things:

        1. Whether a pointer is typed as pointing to a const object.
        2. Whether a pointer is itself const.

        In case 1, you cannot use the pointer to modify what is pointed to (i.e.,
        you cannot change the object at the memory address contained in the
        pointer). In case 2, you cannot modify the pointer itself (i.e., you cannot
        change it so it points to a different memory address).

        There are four possible combinations of pointer const-ness, examples of
        which are given below:

        // not const at all
        A. TestClass * ptr;

        // non-const pointer to a const object
        B. const TestClass * ptr_to_const;

        // const pointer to non-const object
        C. TestClass * const const_ptr;

        // const pointer to const object
        D. const TestClass * const const_ptr_to_co nst;

        Which category a pointer falls into depends on where the const is in
        relation to the asterisk. If the const is to the left of the asterisk, that
        makes it a pointer to a const object (case 1 above). If the pointer is to
        the right of the asterisk, that makes it a const pointer (case 2 above).

        The rules regarding these various pointer types are as follows:

        Pointers to non-const objects ---- A and C above --- can be used to call
        non-const member functions. However, if a object is declared to be of const
        type, then a pointer to non-const objects cannot store the object's address,
        i.e., an attempt to assign the address of a const object to a pointer to
        non-const objects will fail to compile. Thus it is not possible to use
        pointers to non-const objects to call non-const member functions on a const
        object.

        Pointers to const objects --- B and D above --- cannot be used to call
        non-const member functions but can store the address of both const and
        non-const objects.

        Putting these two rules together, we see that there is no pointer that
        allows you to call a non-const member function on a const object. This would
        seem to be the thing that matters as far as respecting const qualifiers
        goes.


        --
        John Carson
        1. To reply to email address, remove donald
        2. Don't reply to email address (post here instead)

        Comment

        • Jonathan Turkanis

          #5
          Re: why does const not work on pointed objects?


          "Andrey Tarasevich" <andreytarasevi ch@hotmail.com> wrote in message
          news:102ghrfq98 1mg8f@news.supe rnews.com...[color=blue]
          > Corno wrote:[color=green]
          > > ...
          > > There's probably a good reason why a const object can call non[/color][/color]
          const[color=blue][color=green]
          > > functions of the objects where it's member pointers point to.
          > > I just don't see it. For me, that makes the the const keyword a[/color][/color]
          lot less[color=blue][color=green]
          > > usable.
          > > Can anybody tell me what that good reason is?
          > > ...[/color]
          >
          > Because you are dealing with two completely unrelated objects. Would[/color]
          you[color=blue]
          > please clarify, why do you think that constness of one object (or of[/color]
          an[color=blue]
          > access path to one object) should somehow implicate constness of a
          > completely unrelated other object (or of an access path to other[/color]
          object)?[color=blue]
          >[/color]

          There was recently a rather heated argument about this issue on the
          boost developers list. One participant seemed to be advocating
          'deep-constness' as the desirable default behavior for pointers and
          smart pointers.

          See http://lists.boost.org/MailArchives/boost/msg57577.php and
          following.

          It was very bloody -- defintely not suitable for children. The
          traditional semantics emerged victorious, at least for now ...

          Jonathan


          Comment

          • Corno

            #6
            Re: why does const not work on pointed objects?


            "Andrey Tarasevich" <andreytarasevi ch@hotmail.com> wrote in message
            news:102ghrfq98 1mg8f@news.supe rnews.com...[color=blue]
            > Corno wrote:[color=green]
            > > ...
            > > There's probably a good reason why a const object can call non const
            > > functions of the objects where it's member pointers point to.
            > > I just don't see it. For me, that makes the the const keyword a lot less
            > > usable.
            > > Can anybody tell me what that good reason is?
            > > ...[/color]
            >
            > Because you are dealing with two completely unrelated objects.[/color]

            I do not agree with your statement here. The fact that one object stores a
            pointer to the other already means that they are not 'completely unrelated'.
            A good example is the pimpl idiom; the implementation is definately related
            to the abstraction. However, as long as the implementation is not const (Imp
            const * const or Imp const *) it is perfectly legal to declare a const
            function in the abstraction that calls a non const function of the
            implementation.

            Corno
            [color=blue]
            > Would you
            > please clarify, why do you think that constness of one object (or of an
            > access path to one object) should somehow implicate constness of a
            > completely unrelated other object (or of an access path to other object)?
            >
            > --
            > Best regards,
            > Andrey Tarasevich
            >[/color]


            Comment

            • John Harrison

              #7
              Re: why does const not work on pointed objects?


              "Corno" <corno@%spam%.d ds.nl> wrote in message
              news:c0a23u$7af $1@reader08.wxs .nl...[color=blue]
              >
              > "Andrey Tarasevich" <andreytarasevi ch@hotmail.com> wrote in message
              > news:102ghrfq98 1mg8f@news.supe rnews.com...[color=green]
              > > Corno wrote:[color=darkred]
              > > > ...
              > > > There's probably a good reason why a const object can call non const
              > > > functions of the objects where it's member pointers point to.
              > > > I just don't see it. For me, that makes the the const keyword a lot[/color][/color][/color]
              less[color=blue][color=green][color=darkred]
              > > > usable.
              > > > Can anybody tell me what that good reason is?
              > > > ...[/color]
              > >
              > > Because you are dealing with two completely unrelated objects.[/color]
              >
              > I do not agree with your statement here. The fact that one object stores a
              > pointer to the other already means that they are not 'completely[/color]
              unrelated'.[color=blue]
              > A good example is the pimpl idiom; the implementation is definately[/color]
              related[color=blue]
              > to the abstraction. However, as long as the implementation is not const[/color]
              (Imp[color=blue]
              > const * const or Imp const *) it is perfectly legal to declare a const
              > function in the abstraction that calls a non const function of the
              > implementation.
              >
              > Corno
              >[/color]

              I think the point is that any relationship that exists between two classes
              is imposed by you. Since you are writing the code it is your responsibility
              to get the relationship right, not the language's. In the case you quote its
              not difficult.

              One the other hand if the rule you want existed in C++, then it might reduce
              the chances of trivial error in the pimpl idiom, but it would also
              considerable reduce the flexibility of the language for programs which have
              more loosely related objects.

              E.g.

              class Block
              {
              public:
              void move_to(int x, int y) const
              {
              world->move_to(this , x, y);
              }
              private:
              BlockWorld * world;
              };

              class BlockWorld
              {
              public:
              void move_to(Block *, int x, int y);
              };

              Blocks don't hold their position, a blocks position is not part of its
              identity, therefore Block::move_to is quite reasonably a const member
              function. However there is a BlockWorld object which maintains a list of
              blocks and their positions, obviously BlockWorld::mov e_to cannot be a const
              function.

              john


              Comment

              • Corno

                #8
                Re: why does const not work on pointed objects?

                > I suspect that you are confusing two things:[color=blue]
                >
                > 1. Whether a pointer is typed as pointing to a const object.
                > 2. Whether a pointer is itself const.
                >[/color]
                --snip--[color=blue]
                >
                > Putting these two rules together, we see that there is no pointer that
                > allows you to call a non-const member function on a const object. This[/color]
                would[color=blue]
                > seem to be the thing that matters as far as respecting const qualifiers
                > goes.
                >[/color]
                This explains about the restrictions the standard *does* impose. However, my
                argument was not that the standard is too strict, but too loose.
                To me it would seem logical if a const object cannot call *any* non const
                member functions of pointee objects (except if the pointees are specifically
                marked as 'mutable').

                Corno


                Comment

                • Corno

                  #9
                  Re: why does const not work on pointed objects?

                  >[color=blue]
                  > I think the point is that any relationship that exists between two classes
                  > is imposed by you. Since you are writing the code it is your[/color]
                  responsibility[color=blue]
                  > to get the relationship right, not the language's. In the case you quote[/color]
                  its[color=blue]
                  > not difficult.
                  >[/color]
                  In that case you could throw out the whole const keyword;
                  "it's your responsibility to write correct code" ;)
                  [color=blue]
                  > One the other hand if the rule you want existed in C++, then it might[/color]
                  reduce[color=blue]
                  > the chances of trivial error in the pimpl idiom, but it would also
                  > considerable reduce the flexibility of the language for programs which[/color]
                  have[color=blue]
                  > more loosely related objects.
                  >[/color]
                  --snip--[color=blue]
                  >
                  > Blocks don't hold their position, a blocks position is not part of its
                  > identity, therefore Block::move_to is quite reasonably a const member
                  > function. However there is a BlockWorld object which maintains a list of
                  > blocks and their positions, obviously BlockWorld::mov e_to cannot be a[/color]
                  const[color=blue]
                  > function.
                  >[/color]
                  Like I stated in the other post; this would be a situation where you would
                  have to use 'mutable'.
                  IOW the function cannot change anything, except when explicitly stated.

                  Corno


                  Comment

                  • Andrey Tarasevich

                    #10
                    Re: why does const not work on pointed objects?

                    Corno wrote:[color=blue][color=green][color=darkred]
                    >> > ...
                    >> > There's probably a good reason why a const object can call non const
                    >> > functions of the objects where it's member pointers point to.
                    >> > I just don't see it. For me, that makes the the const keyword a lot less
                    >> > usable.
                    >> > Can anybody tell me what that good reason is?
                    >> > ...[/color]
                    >>
                    >> Because you are dealing with two completely unrelated objects.[/color]
                    >
                    > I do not agree with your statement here. The fact that one object stores a
                    > pointer to the other already means that they are not 'completely unrelated'.
                    > A good example is the pimpl idiom; the implementation is definately related
                    > to the abstraction. However, as long as the implementation is not const (Imp
                    > const * const or Imp const *) it is perfectly legal to declare a const
                    > function in the abstraction that calls a non const function of the
                    > implementation.[/color]

                    At the language level storing inside an object a pointer to another
                    object is not an idiom, it is nothing more than one of the core language
                    features. This feature can be used to implement a variety of completely
                    different idioms. You just named one of them, which follows the concept
                    of 'aggregation'. Yes, in case of 'aggregation' it is perfectly logical
                    to propagate the constness from enclosing object to the aggregated
                    object. However, there are many other idioms that can be implemented
                    using such a pointer. For example, a concept of 'object reference'
                    (which is not an 'aggregation') does not imply that the constness should
                    be propagated.

                    At core language level C++ tries not to limit your choice of programing
                    idioms. If you are trying to implement an idiom that needs
                    const-propagation for pointer-based aggregation - implement this
                    propagation yourself. For example, when implementing pimpl idiom refrain
                    from accessing the implementation pointer directly. Provide a pair of
                    accessor functions and use them instead

                    class Interface
                    {
                    ...
                    private:
                    Implementation* pimpl;
                    Implementation* get_impl() { return pimpl; }
                    const Implementation* get_impl() const { return pimpl; }
                    };

                    That way you'll achieve the desired const-propagation effect.

                    --
                    Best regards,
                    Andrey Tarasevich

                    Comment

                    • Dylan Nicholson

                      #11
                      Re: why does const not work on pointed objects?

                      Andrey Tarasevich <andreytarasevi ch@hotmail.com> wrote in message news:<102ghrfq9 81mg8f@news.sup ernews.com>...[color=blue]
                      > Corno wrote:[color=green]
                      > > ...
                      > > There's probably a good reason why a const object can call non const
                      > > functions of the objects where it's member pointers point to.
                      > > I just don't see it. For me, that makes the the const keyword a lot less
                      > > usable.
                      > > Can anybody tell me what that good reason is?
                      > > ...[/color]
                      >
                      > Because you are dealing with two completely unrelated objects. Would you
                      > please clarify, why do you think that constness of one object (or of an
                      > access path to one object) should somehow implicate constness of a
                      > completely unrelated other object (or of an access path to other object)?[/color]

                      I assume the OP is referring to something like the following:

                      #include <string>

                      struct foo
                      {
                      void bar() const
                      {
                      data = "hello"; // not allowed
                      }
                      std::string data;
                      };

                      struct foo2
                      {
                      void bar() const
                      {
                      *data = "hello"; // allowed
                      }
                      std::string* data;
                      };

                      In which case, I assume the OP's point is that the fact that 'data' is
                      held via a pointer makes it no less part of the object's data, so why
                      should you get non-const access to it from a const member function?
                      It basically makes constness useless with something like the pimpl
                      idiom, for instance. The problem is that, as you say, in some cases
                      the data member pointer may not point to data that is instrinsically
                      part of the class, in which case the current rules make sense.
                      There is, of course, a solution: wrap the pointer up in a class
                      specifically designed to handle this (*not* std::auto_ptr<> , btw):

                      struct string_ptr
                      {
                      /* constructor/destructor presumably to new/delete ptr */
                      std::string& operator* () { return *ptr; }
                      const std::string& operator* () const { return *ptr; }
                      private:
                      std::string* ptr;
                      };

                      struct foo3
                      {
                      void bar() const
                      {
                      *data = "hello"; // not allowed
                      }
                      void bar()
                      {
                      *data = "hello"; // allowed
                      }
                      string_ptr data;
                      };


                      Dylan

                      Comment

                      • Corno

                        #12
                        Re: why does const not work on pointed objects?

                        > If you are trying to implement an idiom that needs[color=blue]
                        > const-propagation for pointer-based aggregation - implement this
                        > propagation yourself. For example, when implementing pimpl idiom refrain
                        > from accessing the implementation pointer directly. Provide a pair of
                        > accessor functions and use them instead
                        >
                        > class Interface
                        > {
                        > ...
                        > private:
                        > Implementation* pimpl;
                        > Implementation* get_impl() { return pimpl; }
                        > const Implementation* get_impl() const { return pimpl; }
                        > };
                        >
                        > That way you'll achieve the desired const-propagation effect.
                        >[/color]
                        Interesting approach, thanks!

                        Corno


                        Comment

                        • John Harrison

                          #13
                          Re: why does const not work on pointed objects?


                          "Corno" <corno@%spam%.d ds.nl> wrote in message
                          news:c0a60l$bdd $1@reader08.wxs .nl...[color=blue][color=green]
                          > >
                          > > I think the point is that any relationship that exists between two[/color][/color]
                          classes[color=blue][color=green]
                          > > is imposed by you. Since you are writing the code it is your[/color]
                          > responsibility[color=green]
                          > > to get the relationship right, not the language's. In the case you quote[/color]
                          > its[color=green]
                          > > not difficult.
                          > >[/color]
                          > In that case you could throw out the whole const keyword;
                          > "it's your responsibility to write correct code" ;)[/color]

                          Not at all. Which functions are const is visible to the user. The internal
                          pointers of your class are not. That's the whole point.
                          [color=blue]
                          >[color=green]
                          > > One the other hand if the rule you want existed in C++, then it might[/color]
                          > reduce[color=green]
                          > > the chances of trivial error in the pimpl idiom, but it would also
                          > > considerable reduce the flexibility of the language for programs which[/color]
                          > have[color=green]
                          > > more loosely related objects.
                          > >[/color]
                          > --snip--[color=green]
                          > >
                          > > Blocks don't hold their position, a blocks position is not part of its
                          > > identity, therefore Block::move_to is quite reasonably a const member
                          > > function. However there is a BlockWorld object which maintains a list of
                          > > blocks and their positions, obviously BlockWorld::mov e_to cannot be a[/color]
                          > const[color=green]
                          > > function.
                          > >[/color]
                          > Like I stated in the other post; this would be a situation where you would
                          > have to use 'mutable'.
                          > IOW the function cannot change anything, except when explicitly stated.
                          >[/color]

                          I see mutable as being used for cached values and the like, not for
                          expressing the relationship between classes, which is far too complex to be
                          captured in a single concept like mutable. Just attend some OO design
                          classes if you don't believe me!
                          [color=blue]
                          > Corno
                          >[/color]

                          john


                          Comment

                          • Corno

                            #14
                            Re: why does const not work on pointed objects?

                            > I assume the OP is referring to something like the following:[color=blue]
                            >
                            > #include <string>
                            >
                            > struct foo
                            > {
                            > void bar() const
                            > {
                            > data = "hello"; // not allowed
                            > }
                            > std::string data;
                            > };
                            >
                            > struct foo2
                            > {
                            > void bar() const
                            > {
                            > *data = "hello"; // allowed
                            > }
                            > std::string* data;
                            > };
                            >
                            > In which case, I assume the OP's point is that the fact that 'data' is
                            > held via a pointer makes it no less part of the object's data, so why
                            > should you get non-const access to it from a const member function?[/color]

                            so the value of using const in a public member function of a class (it's
                            interface) is changed for me.
                            It's no guarantee to the user that nothing will change; it imposes a IMHO
                            strange restriction on the implementation; a part of the related data of an
                            instance, eg, only the direct member data is not allowed to change. But as
                            the example above shows, the same behaviour of the class can be implemented
                            in another way (which is not a hack to me) that is not hindered by const.
                            The only thing it does is that it creates 2 interfaces to the same class, it
                            makes a distinction between all users into 2 groups; users that have full
                            access to all the member functions and users that can only use the const
                            functions (either or not really const).

                            Corno


                            Comment

                            • Corno

                              #15
                              Re: why does const not work on pointed objects?

                              [color=blue]
                              >
                              > I see mutable as being used for cached values and the like, not for
                              > expressing the relationship between classes, which is far too complex to[/color]
                              be[color=blue]
                              > captured in a single concept like mutable. Just attend some OO design
                              > classes if you don't believe me!
                              >[/color]
                              You are correct, 'mutable' is not an elegant 'keyword' for such a situation
                              However, backtracking on your previous example about the Block not being
                              mutated when moved;
                              I would have to disagree. To me, moving the block mutates it as well so the
                              function should not be const.
                              For me, it would be more logical if 'const' would guarantee that it would
                              not change the state of the 'model'.

                              Corno


                              Comment

                              Working...