const ref vs. pointer

Discussion in 'C++' started by Luca, Nov 2, 2006.

  1. Luca

    Luca Guest

    I have 2 questions:

    1. Which one is the best: Returning member variables of the class by const
    ref or returning by pointer?

    e.g.:

    Employee* GetEmployee() const;
    Employee& GetEmployee() const;

    2. Which one is best: Passing a variable by const ref or by pointer?

    e.g.:

    void SetSalary(Employee* e);
    void SetSalary(const Employee& e);

    Thanks
     
    Luca, Nov 2, 2006
    #1
    1. Advertising

  2. Luca

    Guest

    there is no clear cut best option among these. the answer being
    dependent upon the way your function behaves.

    the most important difference between the reference and pointer is that
    pointer can be null but reference always points to some valid object.

    So if GetEmployee will sometime have to return null Employee use
    pointer other wise use reference. The reference will help because you
    will always be sure that the reference points to some valid Employee.

    Reference are alwyas constants, you cannot change the reference to
    ponit to some other object. So you can do away with the const
    specifier. And as i said before, if the objects are always valid,
    reference are always better than pointers.

    thanks
    ravinder thakur

    Luca wrote:
    > I have 2 questions:
    >
    > 1. Which one is the best: Returning member variables of the class by const
    > ref or returning by pointer?
    >
    > e.g.:
    >
    > Employee* GetEmployee() const;
    > Employee& GetEmployee() const;
    >
    > 2. Which one is best: Passing a variable by const ref or by pointer?
    >
    > e.g.:
    >
    > void SetSalary(Employee* e);
    > void SetSalary(const Employee& e);
    >
    > Thanks
     
    , Nov 2, 2006
    #2
    1. Advertising

  3. Luca

    peter koch Guest

    Luca wrote:
    > I have 2 questions:
    >
    > 1. Which one is the best: Returning member variables of the class by const
    > ref or returning by pointer?
    >
    > e.g.:
    >
    > Employee* GetEmployee() const;
    > Employee& GetEmployee() const;

    Employee const&
    >
    > 2. Which one is best: Passing a variable by const ref or by pointer?
    >
    > e.g.:
    >
    > void SetSalary(Employee* e);
    > void SetSalary(const Employee& e);
    >

    In both cases (as in all other aspects of life ;-) choose the construct
    that suits your purpose best. Here, it seems evident that you should
    use a const&. There will always be a value to return and there must
    always be a value to supply. Using a pointer sends a different message
    and invites to e.g. call SetSalary(0).

    /Peter
     
    peter koch, Nov 2, 2006
    #3
  4. Luca

    benben Guest

    Luca wrote:
    > I have 2 questions:
    >
    > 1. Which one is the best: Returning member variables of the class by const
    > ref or returning by pointer?
    >
    > e.g.:
    >
    > Employee* GetEmployee() const;
    > Employee& GetEmployee() const;


    If the aboves return member variables then they should return pointer or
    reference to const.

    const Employee* GetEmployee() const;
    const Employee& GetEmployee() const;

    Neither is better than the other although the latter might be more
    natural for the caller:

    cout << *(x.GetEmployee()); // using a pointer returned

    vs

    cout << x.GetEmployee(); // using a reference returned

    But it highly depends on your coding style and context.

    >
    > 2. Which one is best: Passing a variable by const ref or by pointer?
    >
    > e.g.:
    >
    > void SetSalary(Employee* e);
    > void SetSalary(const Employee& e);


    A pointer should not be compared to a reference to const. You either
    compare a pointer with a reference

    // if the argument is to be changed
    void SetSalary(Employee* e);
    void SetSalary(Employee& e);

    or a point to const with a reference to const

    // if the argument is not to be changed
    void SetSalary(const Employee* e);
    void SetSalary(const Employee& e);

    Whichever case you have, it is up to you whether you choose to use
    pointer or reference.

    >
    > Thanks


    Ben
     
    benben, Nov 2, 2006
    #4
  5. Luca

    toton Guest

    Luca wrote:
    > I have 2 questions:
    >
    > 1. Which one is the best: Returning member variables of the class by const
    > ref or returning by pointer?
    >
    > e.g.:
    >
    > Employee* GetEmployee() const;
    > Employee& GetEmployee() const;
    >
    > 2. Which one is best: Passing a variable by const ref or by pointer?
    >
    > e.g.:
    >
    > void SetSalary(Employee* e);
    > void SetSalary(const Employee& e);


    Compare between
    void SetSalary(const Employee* e);
    void SetSalary(const Employee& e);
    Now answers,
    For return by pointer & reference
    1) GetEmployee can't return NULL => use reference.
    also you have operator overloading on Employee => highly advised to
    use reference.
    2) GetEmployee can return NULL, use pointer.
    Same for Setters.
    Two points to remember,
    1) C++ promotes reference idea for pass by reference.
    Thus Employee e;
    SetSalary(e); promotes value e to reference e (highly advices,
    generated a better code) , which it doesn't do automatically for
    pointer.
    2) Employee e = GetEmployee() ; demotes reference to value (highly
    discouraged, causes all sorts of problem) , which it doesn't do for
    pointer. The effect for missing one & can be catastrophic.
    Thus, while passing by reference, just do it blindly. While
    returning reference, don't forget to check. Compiler is not there to
    complain this "mistake" which it will do for pointer.
    > Thanks
     
    toton, Nov 2, 2006
    #5
  6. Luca

    Salt_Peter Guest

    Luca wrote:
    > I have 2 questions:
    >
    > 1. Which one is the best: Returning member variables of the class by const
    > ref or returning by pointer?
    >
    > e.g.:
    >
    > Employee* GetEmployee() const;
    > Employee& GetEmployee() const;


    Neither is better, both are equally dangerous.
    They give unrestricted access to the encapsulated member.
    What you should be asking is which is the better of the following:

    Employee GetEmployee() const;
    const Employee* GetEmplotee() const;
    const Employee* const GetEmployee() const;
    const Employee& GetEmployee() const;

    >
    > 2. Which one is best: Passing a variable by const ref or by pointer?
    >
    > e.g.:
    >
    > void SetSalary(Employee* e);


    // pass by const ptr to const Employee
    void SetSalary(const Employee* const p_e);

    > void SetSalary(const Employee& e);
    >
    > Thanks


    They both serve their purpose although the reference is guarenteed to
    be a valid object.
     
    Salt_Peter, Nov 2, 2006
    #6
  7. Luca

    loufoque Guest

    Luca wrote:
    > I have 2 questions:
    >
    > 1. Which one is the best: Returning member variables of the class by const
    > ref or returning by pointer?


    Never use pointers unless you have to.
    Never use raw pointers when you want to reference dynamically allocated
    data.

    And using pointers instead of references just to have a null value is
    stupid. Use boost.optional for that.

    Oh, and try to learn a bit about constness.
    In your example you're returning a reference, not a reference to a const
    object as you claimed.
     
    loufoque, Nov 2, 2006
    #7
  8. Luca

    Peter Guest

    Salt_Peter wrote:

    > They both serve their purpose although the reference is guarenteed to
    > be a valid object.



    there is no such guaranty. It may be implied that there is always a
    valid object behind but it is entirely possible to have a
    null-reference returned:


    const Object &getObject(vodi)
    {
    Object *p = 0;
    return *p;
    }

    const Object &r = getObject();

    this works fine until somebody tries to derefence the object -- means
    the initialization of the reference does work.
    I think that references to writeable objects are code obfuscation -- I
    try to avoid them unless I have to use them -- e.g. for assignment
    operators or copy constructors (if the object passed cannot be
    constant).
     
    Peter, Nov 2, 2006
    #8
  9. Luca

    Peter Guest

    Salt_Peter wrote:

    > They both serve their purpose although the reference is guarenteed to
    > be a valid object.



    there is no such guaranty. It may be implied that there is always a
    valid object behind but it is entirely possible to have a
    null-reference returned:


    const Object &getObject(vodi)
    {
    Object *p = 0;
    return *p;
    }

    const Object &r = getObject();

    this works fine until somebody tries to derefence the object -- means
    the initialization of the reference does work.
    I think that references to writeable objects are code obfuscation -- I
    try to avoid them unless I have to use them -- e.g. for assignment
    operators or copy constructors (if the object passed cannot be
    constant).
     
    Peter, Nov 2, 2006
    #9
  10. Luca

    Andre Kostur Guest

    "Peter" <> wrote in news:1162507991.607378.77690
    @m7g2000cwm.googlegroups.com:

    >
    > Salt_Peter wrote:
    >
    >> They both serve their purpose although the reference is guarenteed to
    >> be a valid object.

    >
    >
    > there is no such guaranty. It may be implied that there is always a
    > valid object behind but it is entirely possible to have a
    > null-reference returned:


    Not without invoking Undefined Behaviour....

    > const Object &getObject(vodi)
    > {
    > Object *p = 0;
    > return *p;
    > }


    .... like dereferencing a NULL pointer.

    > const Object &r = getObject();
    >
    > this works fine until somebody tries to derefence the object -- means
    > the initialization of the reference does work.


    Nope. There's no guarantee that the initialization of that reference
    "worked". As soon as you invoked Undefined Behaviour, all bets are off.
    Your program could do whatever it wanted.
     
    Andre Kostur, Nov 2, 2006
    #10
  11. Luca

    Salt_Peter Guest

    Andre Kostur wrote:
    > "Peter" <> wrote in news:1162507991.607378.77690
    > @m7g2000cwm.googlegroups.com:
    >
    > >
    > > Salt_Peter wrote:
    > >
    > >> They both serve their purpose although the reference is guarenteed to
    > >> be a valid object.

    > >
    > >
    > > there is no such guaranty. It may be implied that there is always a
    > > valid object behind but it is entirely possible to have a
    > > null-reference returned:

    >
    > Not without invoking Undefined Behaviour....


    thank-you

    >
    > > const Object &getObject(vodi)
    > > {
    > > Object *p = 0;
    > > return *p;
    > > }

    >
    > ... like dereferencing a NULL pointer.
    >
    > > const Object &r = getObject();
    > >
    > > this works fine until somebody tries to derefence the object -- means
    > > the initialization of the reference does work.

    >
    > Nope. There's no guarantee that the initialization of that reference
    > "worked". As soon as you invoked Undefined Behaviour, all bets are off.
    > Your program could do whatever it wanted.


    agreed
     
    Salt_Peter, Nov 3, 2006
    #11
  12. Luca

    Peter Guest

    Andre Kostur wrote:
    > >> They both serve their purpose although the reference is guarenteed to
    > >> be a valid object.

    > >
    > >
    > > there is no such guaranty. It may be implied that there is always a
    > > valid object behind but it is entirely possible to have a
    > > null-reference returned:

    >
    > Not without invoking Undefined Behaviour....
    >
    > > const Object &getObject(vodi)
    > > {
    > > Object *p = 0;
    > > return *p;
    > > }

    >
    > ... like dereferencing a NULL pointer.



    creating a reference is not equal dereferencing a pointer.
    Creating a reference is identical to initializing a pointer.


    > > const Object &r = getObject();
    > >
    > > this works fine until somebody tries to derefence the object -- means
    > > the initialization of the reference does work.

    >
    > Nope. There's no guarantee that the initialization of that reference
    > "worked". As soon as you invoked Undefined Behaviour, all bets are off.
    > Your program could do whatever it wanted.



    I think this is pretty much defined just by the fact that
    when initializing a reference a check for a valid reference would be
    too expensive.
    Dereferencing a null reference may be undefined but initializing it is
    certainly not.
     
    Peter, Nov 15, 2006
    #12
  13. Luca

    Andre Kostur Guest

    "Peter" <> wrote in news:1163624779.810389.126060
    @e3g2000cwe.googlegroups.com:

    >
    > Andre Kostur wrote:
    >> >> They both serve their purpose although the reference is guarenteed

    to
    >> >> be a valid object.
    >> >
    >> >
    >> > there is no such guaranty. It may be implied that there is always a
    >> > valid object behind but it is entirely possible to have a
    >> > null-reference returned:

    >>
    >> Not without invoking Undefined Behaviour....
    >>
    >> > const Object &getObject(vodi)
    >> > {
    >> > Object *p = 0;
    >> > return *p;
    >> > }

    >>
    >> ... like dereferencing a NULL pointer.

    >
    >
    > creating a reference is not equal dereferencing a pointer.
    > Creating a reference is identical to initializing a pointer.


    "return *p;" That dereferences the p pointer. Undefined Behaviour.

    >> > const Object &r = getObject();
    >> >
    >> > this works fine until somebody tries to derefence the object --

    means
    >> > the initialization of the reference does work.

    >>
    >> Nope. There's no guarantee that the initialization of that reference
    >> "worked". As soon as you invoked Undefined Behaviour, all bets are

    off.
    >> Your program could do whatever it wanted.

    >
    >
    > I think this is pretty much defined just by the fact that
    > when initializing a reference a check for a valid reference would be
    > too expensive.


    Irrelevant. The program caused a NULL pointer to be dereferenced. After
    that, the program's behaviour is undefined. It may run until the
    reference is used, it may crash at the point of the NULL pointer
    dereference, it may never crash. Doesn't matter. It's Undefined
    Behaviour.

    > Dereferencing a null reference may be undefined but initializing it is
    > certainly not.


    A NULL pointer is dereferenced. Undefined Behaviour. It doesn't matter
    what you do with it.
     
    Andre Kostur, Nov 15, 2006
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. cppaddict

    converting pointer to const ref

    cppaddict, Oct 14, 2003, in forum: C++
    Replies:
    6
    Views:
    5,356
    cppaddict
    Oct 14, 2003
  2. coala
    Replies:
    3
    Views:
    409
    coala
    Sep 6, 2006
  3. coala
    Replies:
    1
    Views:
    611
    Victor Bazarov
    Sep 6, 2006
  4. Javier
    Replies:
    2
    Views:
    618
    James Kanze
    Sep 4, 2007
  5. Disc Magnet
    Replies:
    1
    Views:
    653
    Ian Collins
    May 6, 2010
Loading...

Share This Page