const ref vs. pointer

L

Luca

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
 
R

ravinderthakur

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
 
P

peter koch

Luca said:
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
 
B

benben

Luca said:
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.

Ben
 
T

toton

Luca said:
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.
 
S

Salt_Peter

Luca said:
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.
 
L

loufoque

Luca said:
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.
 
P

Peter

Salt_Peter said:
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).
 
P

Peter

Salt_Peter said:
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).
 
A

Andre Kostur

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.
 
S

Salt_Peter

Andre said:
Not without invoking Undefined Behaviour....
thank-you


... like dereferencing a NULL pointer.


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
 
P

Peter

Andre said:
Not without invoking Undefined Behaviour....


... like dereferencing a NULL pointer.


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

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.
 
A

Andre Kostur

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.
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top