pointer & reference doubt!

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

    pointer & reference doubt!

    HI,
    One more small doubt from today's mail.
    I have certain function which returns a pointer (sometimes a const
    pointer from a const member function).
    And certain member function needs reference (or better a const
    reference).

    for eg,
    const PointRange* points = cc.points(ptAli gned);

    cc.points is a const member function which returns a const pointer to
    class PointRange.
    This member function (from a different class) needs a const reference
    to PointRange.
    convolveNearEdg e(const PointRange& points,const Kernel& kernel, ...) {}


    I am passing it the reference as,
    convolveNearEdg e(*points,getKe rnel1(),velocit y);

    I do not need a null in the function thus a reference. also I make
    assure points passed to convolveNearEdg e is not null.

    My question is, in the process do anywhere copy of the class occures
    silently? I have no problem if it copies a pointer. But do not want a
    copy of the class even temporarily.

    Thus fundamentally , if I have a pointer, say int* x; *x = 10; then
    int& y = *x is essentially a reference to the value pointed by x? and
    without any overload?


    Thanks

  • Victor Bazarov

    #2
    Re: pointer & reference doubt!

    toton wrote:
    I have certain function which returns a pointer (sometimes a const
    pointer from a const member function).
    And certain member function needs reference (or better a const
    reference).
    >
    for eg,
    const PointRange* points = cc.points(ptAli gned);
    >
    cc.points is a const member function which returns a const pointer to
    class PointRange.
    This member function (from a different class) needs a const reference
    to PointRange.
    convolveNearEdg e(const PointRange& points,const Kernel& kernel, ...)
    {}
    >
    >
    I am passing it the reference as,
    convolveNearEdg e(*points,getKe rnel1(),velocit y);
    >
    I do not need a null in the function thus a reference. also I make
    assure points passed to convolveNearEdg e is not null.
    >
    My question is, in the process do anywhere copy of the class occures
    silently?
    Unless there is a conversion from PointRange to something inside the
    'convolveNearEd ge' function... No, returning a pointer does not need
    to make a copy, passing a reference doesn't either.
    I have no problem if it copies a pointer. But do not want a
    copy of the class even temporarily.
    You can always put a breakpoint in the copy constructor and see if it
    gets hit, you know...
    Thus fundamentally , if I have a pointer, say int* x; *x = 10; then
    Ahem... That's a bad idea. 'x' points to nothing and you try to
    dereference it...
    int& y = *x is essentially a reference to the value pointed by x? and
    without any overload?
    Yes, supposedly. Using 'y' after that is just like using '*x'.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask


    Comment

    • toton

      #3
      Re: pointer & reference doubt!


      Victor Bazarov wrote:
      toton wrote:
      I have certain function which returns a pointer (sometimes a const
      pointer from a const member function).
      And certain member function needs reference (or better a const
      reference).

      for eg,
      const PointRange* points = cc.points(ptAli gned);

      cc.points is a const member function which returns a const pointer to
      class PointRange.
      This member function (from a different class) needs a const reference
      to PointRange.
      convolveNearEdg e(const PointRange& points,const Kernel& kernel, ...)
      {}


      I am passing it the reference as,
      convolveNearEdg e(*points,getKe rnel1(),velocit y);

      I do not need a null in the function thus a reference. also I make
      assure points passed to convolveNearEdg e is not null.

      My question is, in the process do anywhere copy of the class occures
      silently?
      >
      Unless there is a conversion from PointRange to something inside the
      'convolveNearEd ge' function... No, returning a pointer does not need
      to make a copy, passing a reference doesn't either.
      >
      I have no problem if it copies a pointer. But do not want a
      copy of the class even temporarily.
      >
      You can always put a breakpoint in the copy constructor and see if it
      gets hit, you know...
      >
      Thus fundamentally , if I have a pointer, say int* x; *x = 10; then
      >
      Ahem... That's a bad idea. 'x' points to nothing and you try to
      dereference it...
      Very bad .... . May be this is the only reason I never use a pointer
      which is not a class member. read the code as . int* x = new int; *x =
      10; int& y = *x;
      and at last delete x;
      int& y = *x is essentially a reference to the value pointed by x? and
      without any overload?
      >
      Yes, supposedly. Using 'y' after that is just like using '*x'.
      >
      V
      Thus i feel that a pointer & reference can be freely interchangable
      without any overhead provided the pointer is pointing to a valid
      object.
      I usually pass a const / non const reference as it always hold a valid
      object & easier syntax. However I prefer return as pointer over
      reference (const / non const) , when I am not supposed to return value,
      because sometimes I forget to work with the reference, and use a copy
      instead, which do not serve the purpose of returning reference.
      like instead of writing
      test11& t1 = t2.t();
      occationally end up with
      test11 t1 = t2.t();
      :(
      Any suggestion regurding this problem?

      Thanks
      --
      Please remove capital 'A's when replying by e-mail
      I do not respond to top-posted replies, please don't ask

      Comment

      • toton

        #4
        Re: pointer & reference doubt!


        Victor Bazarov wrote:
        toton wrote:
        I have certain function which returns a pointer (sometimes a const
        pointer from a const member function).
        And certain member function needs reference (or better a const
        reference).

        for eg,
        const PointRange* points = cc.points(ptAli gned);

        cc.points is a const member function which returns a const pointer to
        class PointRange.
        This member function (from a different class) needs a const reference
        to PointRange.
        convolveNearEdg e(const PointRange& points,const Kernel& kernel, ...)
        {}


        I am passing it the reference as,
        convolveNearEdg e(*points,getKe rnel1(),velocit y);

        I do not need a null in the function thus a reference. also I make
        assure points passed to convolveNearEdg e is not null.

        My question is, in the process do anywhere copy of the class occures
        silently?
        >
        Unless there is a conversion from PointRange to something inside the
        'convolveNearEd ge' function... No, returning a pointer does not need
        to make a copy, passing a reference doesn't either.
        >
        I have no problem if it copies a pointer. But do not want a
        copy of the class even temporarily.
        >
        You can always put a breakpoint in the copy constructor and see if it
        gets hit, you know...
        >
        Thus fundamentally , if I have a pointer, say int* x; *x = 10; then
        >
        Ahem... That's a bad idea. 'x' points to nothing and you try to
        dereference it...
        Very bad .... . May be this is the only reason I never use a pointer
        which is not a class member. read the code as . int* x = new int; *x =
        10; int& y = *x;
        and at last delete x;
        int& y = *x is essentially a reference to the value pointed by x? and
        without any overload?
        >
        Yes, supposedly. Using 'y' after that is just like using '*x'.
        >
        V
        Thus i feel that a pointer & reference can be freely interchangable
        without any overhead provided the pointer is pointing to a valid
        object.
        I usually pass a const / non const reference as it always hold a valid
        object & easier syntax. However I prefer return as pointer over
        reference (const / non const) , when I am not supposed to return value,
        because sometimes I forget to work with the reference, and use a copy
        instead, which do not serve the purpose of returning reference.
        like instead of writing
        test11& t1 = t2.t();
        occationally end up with
        test11 t1 = t2.t();
        :(
        Any suggestion regurding this problem?

        Thanks
        --
        Please remove capital 'A's when replying by e-mail
        I do not respond to top-posted replies, please don't ask

        Comment

        • Victor Bazarov

          #5
          Re: pointer & reference doubt!

          toton wrote:
          Victor Bazarov wrote:
          >toton wrote:
          >>[...]
          >>Thus fundamentally , if I have a pointer, say int* x; *x = 10; then
          >>
          >Ahem... That's a bad idea. 'x' points to nothing and you try to
          >dereference it...
          Very bad .... . May be this is the only reason I never use a pointer
          which is not a class member. read the code as . int* x = new int; *x =
          10; int& y = *x;
          and at last delete x;
          :-)

          Usually

          int* x = new int(10);

          is preferred over

          int* x = new int;
          *x = 10;

          It would be a good habit to get into...
          >>int& y = *x is essentially a reference to the value pointed by x?
          >>and without any overload?
          >>
          >Yes, supposedly. Using 'y' after that is just like using '*x'.
          >>
          >V
          Thus i feel that a pointer & reference can be freely interchangable
          without any overhead provided the pointer is pointing to a valid
          object.
          Well, yes, that's true. Remember, though, that if you want to use any
          overloaded operators, you have to write (*ptr). Kinda ugly. But you
          are right, in that case there is only the syntactical difference.
          I usually pass a const / non const reference as it always hold a valid
          object & easier syntax. However I prefer return as pointer over
          reference (const / non const) , when I am not supposed to return
          value, because sometimes I forget to work with the reference, and use
          a copy instead, which do not serve the purpose of returning reference.
          Returning a copy does serve its purpose, though. It's not the same as
          returning a reference, and not only WRT copying.
          like instead of writing
          test11& t1 = t2.t();
          occationally end up with
          test11 t1 = t2.t();
          :(
          Any suggestion regurding this problem?
          "Regurding" ?

          Anyway, just be careful. If you want to weed out all places where you
          initialise an object (instead of a reference), disable the copy c-tor
          and the compiler will barf. [of course it will barf on legal copying
          as well, and you'll have to deal with that]. After removing all those
          unwanted object copy-initialisations , re-enable the copy c-tor (if you
          need it, that is).

          V
          --
          Please remove capital 'A's when replying by e-mail
          I do not respond to top-posted replies, please don't ask


          Comment

          • toton

            #6
            Re: pointer & reference doubt!


            Victor Bazarov wrote:
            toton wrote:
            Victor Bazarov wrote:
            toton wrote:
            >[...]
            >Thus fundamentally , if I have a pointer, say int* x; *x = 10; then
            >
            Ahem... That's a bad idea. 'x' points to nothing and you try to
            dereference it...
            Very bad .... . May be this is the only reason I never use a pointer
            which is not a class member. read the code as . int* x = new int; *x =
            10; int& y = *x;
            and at last delete x;
            >
            :-)
            >
            Usually
            >
            int* x = new int(10);
            >
            is preferred over
            >
            int* x = new int;
            *x = 10;
            >
            It would be a good habit to get into...
            >
            >int& y = *x is essentially a reference to the value pointed by x?
            >and without any overload?
            >
            Yes, supposedly. Using 'y' after that is just like using '*x'.
            >
            V
            Thus i feel that a pointer & reference can be freely interchangable
            without any overhead provided the pointer is pointing to a valid
            object.
            >
            Well, yes, that's true. Remember, though, that if you want to use any
            overloaded operators, you have to write (*ptr). Kinda ugly. But you
            are right, in that case there is only the syntactical difference.
            >
            I usually pass a const / non const reference as it always hold a valid
            object & easier syntax. However I prefer return as pointer over
            reference (const / non const) , when I am not supposed to return
            value, because sometimes I forget to work with the reference, and use
            a copy instead, which do not serve the purpose of returning reference.
            >
            Returning a copy does serve its purpose, though. It's not the same as
            returning a reference, and not only WRT copying.
            Yes, returning reference is different than returning copy. I am
            comparing returning reference and returning pointer. Not them with
            returning copy.
            like instead of writing
            test11& t1 = t2.t();
            occationally end up with
            test11 t1 = t2.t();
            :(
            Any suggestion regurding this problem?
            >
            "Regurding" ?
            Thus, when I need to return the class member object instead to
            1) someone modify it (may be rare case)
            2) const reference / pointer , just for user to use it.
            Now if I need to return a object as reference just for modification (
            or const object just for usage, and the object is big, and ''assume"
            return value optimization is not there, so return by value is an
            overhead)
            Then,
            If I have class like
            lass test11{
            public:
            test11(int x){ }
            private:
            //test11(const test11& t);
            };
            class test22{
            private:
            test11* _t;
            public:
            test11& t(){
            return *_t;
            }
            };

            Now,
            test22 t2;
            test11& t1 = t2.t();
            This statement serves purpose, as I want user to "use test11 to use and
            modify" not a copy of it. (may be, because I want it, or because it is
            big enough not to be copied)
            However by mistake if the user writes,
            test22 t2;
            test11 t1 = t2.t();
            He unknowingly gets a copy and modifies it.
            The same may be true if I return a const reference.
            One method to prevent such mistake is to make the copy ctor private, or
            not defined. However that may not be the solution as,
            1) test11 may need copy ctor (say, test22 stores a vector<test11>
            instead a single one)
            2) I am not interested to prevent copy permanently, I just want to warn
            about the mistake done "unknowingl y"
            Two solution so far I can think,
            1) return a pointer / const pointer instead of reference/ const
            reference.
            Yes, as you suggested, if test11 has overloaded operator then direct
            use of the class may be writing one more line to convert the pointer to
            reference and then use it.
            2) marke the copy ctor explicit.
            Thus the code
            test11 t1 = t2.t(); wont work. One need to write either
            test11& t1 = t2.t(); =which is what I wanted usually.
            or test11 t1(t2.t()); =which shows user clearly wants a copy.
            I am seeking some advice "regarding" this kind of problem.
            >
            Anyway, just be careful. If you want to weed out all places where you
            initialise an object (instead of a reference), disable the copy c-tor
            and the compiler will barf. [of course it will barf on legal copying
            as well, and you'll have to deal with that]. After removing all those
            unwanted object copy-initialisations , re-enable the copy c-tor (if you
            need it, that is).
            I do it whenever possible. I can not do it when I need one - to -many
            or many-to-one composition (association, aggregation) , as I usually
            use stl containers for that purpose. However for any one-to-one
            association / aggregation that is possible.

            Many many thanks for the reply.
            V
            --
            Please remove capital 'A's when replying by e-mail
            I do not respond to top-posted replies, please don't ask

            Comment

            • Victor Bazarov

              #7
              Re: pointer &amp; reference doubt!

              toton wrote:
              [..]
              Thus, when I need to return the class member object instead to
              1) someone modify it (may be rare case)
              2) const reference / pointer , just for user to use it.
              Now if I need to return a object as reference just for modification (
              or const object just for usage, and the object is big, and ''assume"
              return value optimization is not there, so return by value is an
              overhead)
              Then,
              If I have class like
              lass test11{
              public:
              test11(int x){ }
              private:
              //test11(const test11& t);
              };
              class test22{
              private:
              test11* _t;
              public:
              test11& t(){
              return *_t;
              }
              };
              >
              Now,
              test22 t2;
              test11& t1 = t2.t();
              This statement serves purpose, as I want user to "use test11 to use
              and modify" not a copy of it. (may be, because I want it, or because
              it is big enough not to be copied)
              However by mistake if the user writes,
              test22 t2;
              test11 t1 = t2.t();
              He unknowingly gets a copy and modifies it.
              Why "unknowingl y"? Why don't you trust your user to do the right thing?
              The same may be true if I return a const reference.
              Yes. So?
              One method to prevent such mistake is to make the copy ctor private,
              or not defined. However that may not be the solution as,
              1) test11 may need copy ctor (say, test22 stores a vector<test11>
              instead a single one)
              2) I am not interested to prevent copy permanently, I just want to
              warn about the mistake done "unknowingl y"
              Two solution so far I can think,
              1) return a pointer / const pointer instead of reference/ const
              reference.
              Thinking back, you're trying to prevent the user from doing what maybe
              the user wholeheartedly intends. There is no reason. You help the user
              to avoid copying by returning a reference. What the user does with it
              is not your business any more.

              Same with pointers.
              Yes, as you suggested, if test11 has overloaded operator then direct
              use of the class may be writing one more line to convert the pointer
              to reference and then use it.
              2) marke the copy ctor explicit.
              Thus the code
              test11 t1 = t2.t(); wont work. One need to write either
              test11& t1 = t2.t(); =which is what I wanted usually.
              or test11 t1(t2.t()); =which shows user clearly wants a copy.
              I am seeking some advice "regarding" this kind of problem.
              I think you're seeing a problem where there isn't any.
              [..]
              V
              --
              Please remove capital 'A's when replying by e-mail
              I do not respond to top-posted replies, please don't ask


              Comment

              • toton

                #8
                Re: pointer &amp; reference doubt!


                Victor Bazarov wrote:
                toton wrote:
                [..]
                Thus, when I need to return the class member object instead to
                1) someone modify it (may be rare case)
                2) const reference / pointer , just for user to use it.
                Now if I need to return a object as reference just for modification (
                or const object just for usage, and the object is big, and ''assume"
                return value optimization is not there, so return by value is an
                overhead)
                Then,
                If I have class like
                lass test11{
                public:
                test11(int x){ }
                private:
                //test11(const test11& t);
                };
                class test22{
                private:
                test11* _t;
                public:
                test11& t(){
                return *_t;
                }
                };

                Now,
                test22 t2;
                test11& t1 = t2.t();
                This statement serves purpose, as I want user to "use test11 to use
                and modify" not a copy of it. (may be, because I want it, or because
                it is big enough not to be copied)
                However by mistake if the user writes,
                test22 t2;
                test11 t1 = t2.t();
                He unknowingly gets a copy and modifies it.
                >
                Why "unknowingl y"? Why don't you trust your user to do the right thing?
                >
                The same may be true if I return a const reference.
                >
                Yes. So?
                >
                One method to prevent such mistake is to make the copy ctor private,
                or not defined. However that may not be the solution as,
                1) test11 may need copy ctor (say, test22 stores a vector<test11>
                instead a single one)
                2) I am not interested to prevent copy permanently, I just want to
                warn about the mistake done "unknowingl y"
                Two solution so far I can think,
                1) return a pointer / const pointer instead of reference/ const
                reference.
                >
                Thinking back, you're trying to prevent the user from doing what maybe
                the user wholeheartedly intends. There is no reason. You help the user
                to avoid copying by returning a reference. What the user does with it
                is not your business any more.
                >
                Same with pointers.
                >
                Yes, as you suggested, if test11 has overloaded operator then direct
                use of the class may be writing one more line to convert the pointer
                to reference and then use it.
                2) marke the copy ctor explicit.
                Thus the code
                test11 t1 = t2.t(); wont work. One need to write either
                test11& t1 = t2.t(); =which is what I wanted usually.
                or test11 t1(t2.t()); =which shows user clearly wants a copy.
                I am seeking some advice "regarding" this kind of problem.
                >
                I think you're seeing a problem where there isn't any.
                >
                May be. May not be also.
                The reason is that, not every one is an expert C++ programmer. Even a
                large number is not at all a C++ programmer. While parameter passing by
                reference enhances the program(it takes reference, even when exact
                reference is not passed)
                like
                object o; //o is the object itself
                foo(o); //takes the object itself. where void foo(object o);
                foo_ref(o); //takes the reference. where void foo(const object& o);
                So, unknowingly (i.e not going through the reference manual of the API)
                user promotes the idea of rererence!
                Where for return by reference, user unknowingly may ignore the idea of
                reference.
                Pointer is surely not the same case, as it has a syntax difference in
                the function declaration and function calling, otherwise the compiler
                will object. (May be this mistake forced C# to use ref keyward in both
                function declaration and calling).
                Expert programmer do not have a problem. But average programmer may
                fall into silent trap with just an '&' difference.
                One of the problem relating copy ctor as I said, is on the line of
                constructor with a single argument. And copy constructor is also a
                single argument constructor. So the same warning may get applied to
                copy constructor also.
                check http://www.horstmann.com/cpp/pitfalls.html explicit array
                section.
                Also one can notice how many times people ask for a solution for copy
                ctor & assignment operator. And for large class most people give copy
                ctor a deep copy while assignment as shallow one or otherways (like
                blitz array) .

                Anyway, the whole thing is a matter of taste. I thought about that, as
                I checked many programmer do this mistake, and while asked for the
                reason the answer was, "I do it all the time!" , "I hadn't checked the
                API documentation", "Oh! sorry for the mistake", or even "I don't know
                all the details, it is your duty to correct it!".
                Surely it is not valid for you as an user (as you are one of the main
                trouble shooter in this newsgroup , others are surely Kai-Uwe Bux,
                Frederick Gotham, Bart, Rolf Magnus, mlimber). I know that C++ relies
                on programer to write a correct program (on contrary Java forces it.
                Just for comparison check Java & C++ container model, and iterator
                model) , but sometimes the later one is benificial.
                Again, it is the question , to whom you are addressing! . "One size
                does not fit all." True for program as well as programmer!
                Thanks
                [..]
                >
                V
                --
                Please remove capital 'A's when replying by e-mail
                I do not respond to top-posted replies, please don't ask

                Comment

                • Victor Bazarov

                  #9
                  Re: pointer &amp; reference doubt!

                  toton wrote:
                  [..] not every one is an expert C++ programmer. Even a
                  large number is not at all a C++ programmer. While parameter passing
                  by reference enhances the program(it takes reference, even when exact
                  reference is not passed)
                  like
                  object o; //o is the object itself
                  foo(o); //takes the object itself. where void foo(object o);
                  foo_ref(o); //takes the reference. where void foo(const object& o);
                  So, unknowingly (i.e not going through the reference manual of the
                  API) user promotes the idea of rererence!
                  Where for return by reference, user unknowingly may ignore the idea of
                  reference.
                  Yes, that's so. Just like if you ride a bus, you trust the driver to
                  do the right thing, but you don't have the freedom to stop any time you
                  want or to go anywhere you want. When you drive yourself, you do have
                  the freedom, but you have to learn driving, you have to pass the exam,
                  you have to take more risks than a passenger in a bus...

                  Freedom doesn't come cheap. "Unknowingl y" in this case to me is the
                  same as "purposely ignoring". Shouldn't be your problem.
                  [..]
                  Anyway, the whole thing is a matter of taste.
                  I do not agree. It's not. You give them a sophisticated tool (in the
                  form of a library with functions returning *references*). They do not
                  want or do not care to use it to its fullest extend. Who's to blame?
                  I thought about that, as
                  I checked many programmer do this mistake, and while asked for the
                  reason the answer was, [..]
                  Here is the truth: if you strive to protect the users of your "C++"
                  library from making those mistakes, you will *inevitably* recreate Java
                  with all its troubles and problems and niceties and goodness. There is
                  no free cheese, except in a mouse trap.

                  V
                  --
                  Please remove capital 'A's when replying by e-mail
                  I do not respond to top-posted replies, please don't ask


                  Comment

                  Working...