Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Pointers vs References: A Question on Style

Reply
Thread Tools

Pointers vs References: A Question on Style

 
 
Desmond Liu
Guest
Posts: n/a
 
      07-25-2004
I've read articles like Scott Meyer's EC++ (Item 22) that advocate the use
of references when passing parameters. I understand the reasoning behind
using references--you avoid the cost of creating a local object when you
pass an object by reference.

But why use a reference? Is there any inherent advantage of using a
reference over using a pointer? My workplace discourages the use of
pointers when it comes to parameter passing. They always prefer references.

I would argue one reason why we might consider using a pointer is to help
communicate intent. For example, suppose I do the following in C:

#include "foo.h"

int main(int argc, char *argv[])
{
int x=5;

foo(x);

printf("%d\n",x);

return 0;
}

I can guarantee that the program will print '5' because C only supports
pass-by-value. If we're using C++, I can't make that guarantee because
we're allowed to pass-by-reference.

But if I use pointers in parameter-passing, I can use the address-of
operator to communicate intent to other programmers that the parameter
is meant to be modified. For example,

#include "A.h"
#include "X.h"

int main(int argc, char *argv[])
{
A a;
X x;

x.foo(&a); // the intent of this member function is to modify 'a'
// A non-const member function of 'a' will be called.

x.bar(a); // this member function will NOT modify 'a'. Only const
// member functions of 'a' will be called.

std::cout << a << std::endl;

return 0;
}

If I'm having problems with object 'a', I see that member function bar()
will not change object 'a' (by convention), and that my problem is likely
in member function foo(). This is especially useful if I'm sifting through
a large amount of code to track down a problem. By using this convention, I
can save time not having to look at every member function in the class
declaration to see which ones might be the cause of my problem.

Of course, all programmers have to adhere to the convention in order for it
to be useful. So to make a long story short, is it better to do
this:

void x::foo(A* a); // foo() will modify 'a'
void x::bar(const A& a); // bar() will not modify 'a'

Or is it better to do what my workplace requires?

void x::foo(A& a); // foo() will modify 'a'
void x::bar(const A& a); // bar() will not modify 'a'

Am I wrong in suggesting the use of pointers for parameter-passing? Is
there a reason why a reference should always be preferred over a pointer?
My thinking is that this convention would make the C++ code more readable.

----
Desmond

(Remove the 'nospam' from the address for e-mail replies, but I prefer
reply posts to the newsgroup)
 
Reply With Quote
 
 
 
 
JKop
Guest
Posts: n/a
 
      07-25-2004
There are 2 and only 2 situations in which I choose a pointer over a
reference:

1) When it must be re-seated

2) When arrays are involved


> I understand the reasoning behind
> using references--you avoid the cost of
> creating a local object when you
> pass an object by reference.



Incorrect. The nature of today's computers (ie. stack and registers) still
require a hidden pointer. (This is ofcourse where outline functions are
involved).


-JKop
 
Reply With Quote
 
 
 
 
DaKoadMunky
Guest
Posts: n/a
 
      07-25-2004
>There are 2 and only 2 situations in which I choose a pointer over a
>reference:
>
>1) When it must be re-seated
>
>2) When arrays are involved


Another possibility is when a function argument is optional. Pointers can be
null whereas references cannot.
 
Reply With Quote
 
Phlip
Guest
Posts: n/a
 
      07-25-2004
DaKoadMunky wrote:

> >There are 2 and only 2 situations in which I choose a pointer over a
> >reference:
> >
> >1) When it must be re-seated
> >
> >2) When arrays are involved

>
> Another possibility is when a function argument is optional. Pointers can

be
> null whereas references cannot.


One good style rule is to never return null, and never accept null as
parameter.

Follow that rule by passing in instead a Null Object. Consider this code:

void funk(SimCity const * pCity)
{
if (pCity)
pCity->throwParade();
}

Now contrast with this:

class NullCity: public SimCity
{
public: /*virtual*/ void throwParade() {}
};

void funk(SimCity const & aCity)
{
aCity.throwParade();
}

The code simplifies because it pushes behavior behind an interface. The
interface simply promises to its caller that it is doing something, whether
or not it really is. Patterns like this are the heart of OO - programming to
the interface instead of the implementation.

Desmond Liu wrote:

> But why use a reference? Is there any inherent advantage of using a
> reference over using a pointer? My workplace discourages the use of
> pointers when it comes to parameter passing. They always prefer

references.

You need to pair-program with your colleagues, because if they know just
enough C++ to write that advice down, they probably know much more verbally.

The C++ keyword const instructs compilers to reject overt attempts to change
a variable's value. Covert attempts produce undefined behavior, meaning
anything could happen.

C++ functions can take arguments by copy, by address, or by reference.
Ideally, if an object passed into a function does not change, the object
should pass by copy:

void foo(SimCity aCity);

That code is inefficient. In general, programmers should not stress about
efficiency until they have enough code to measure it and find the slow
spots. In this situation, a more efficient implementation is equal cost.
When we pass by reference, our program spends no time making a huge copy of
an entire city:

void foo(SimCity &aCity);

Now if foo() won't change that city's value, the function should declare
that intention in its interface, using pass-by-constant-reference to
simulate pass-by-copy:

void foo(SimCity const &aCity);

That is the most efficient call syntax, cognitively and physically. It's
cognitively efficient because it gives foo() no copied object to foolishly
change and then discard. Statements inside foo() that might attempt to
change that city shouldn't compile. It's physically efficient because the
compiler produces opcodes that only give foo() a handle to an existing city,
without copying it.

C++ supports qualifications before their qualified types, such as "const
SimCity &". I try to write expressions with the most important part first.
There are also subtle technical reasons, in rare situations, to write
"SimCity const &", with the const after its type.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces



 
Reply With Quote
 
Dave Townsend
Guest
Posts: n/a
 
      07-26-2004
I prefer to use references over pointers when I can. One of my strong
reasons is a reference should be referencing a valid object, whereas
a pointer you should always check that it is not NULL before using
it. The code is a little bit less "noisy" since I don't have the -> or *
dererencing to look at.

In situations where an object may be passed or not, or may be present
or not, a pointer is needed.

dave

"Desmond Liu" <(E-Mail Removed)> wrote in message
news:Xns95319D83E984dliu7647nospamshawca@64.59.144 .76...
> I've read articles like Scott Meyer's EC++ (Item 22) that advocate the use
> of references when passing parameters. I understand the reasoning behind
> using references--you avoid the cost of creating a local object when you
> pass an object by reference.
>
> But why use a reference? Is there any inherent advantage of using a
> reference over using a pointer? My workplace discourages the use of
> pointers when it comes to parameter passing. They always prefer

references.
>
> I would argue one reason why we might consider using a pointer is to help
> communicate intent. For example, suppose I do the following in C:
>
> #include "foo.h"
>
> int main(int argc, char *argv[])
> {
> int x=5;
>
> foo(x);
>
> printf("%d\n",x);
>
> return 0;
> }
>
> I can guarantee that the program will print '5' because C only supports
> pass-by-value. If we're using C++, I can't make that guarantee because
> we're allowed to pass-by-reference.
>
> But if I use pointers in parameter-passing, I can use the address-of
> operator to communicate intent to other programmers that the parameter
> is meant to be modified. For example,
>
> #include "A.h"
> #include "X.h"
>
> int main(int argc, char *argv[])
> {
> A a;
> X x;
>
> x.foo(&a); // the intent of this member function is to modify 'a'
> // A non-const member function of 'a' will be called.
>
> x.bar(a); // this member function will NOT modify 'a'. Only const
> // member functions of 'a' will be called.
>
> std::cout << a << std::endl;
>
> return 0;
> }
>
> If I'm having problems with object 'a', I see that member function bar()
> will not change object 'a' (by convention), and that my problem is likely
> in member function foo(). This is especially useful if I'm sifting through
> a large amount of code to track down a problem. By using this convention,

I
> can save time not having to look at every member function in the class
> declaration to see which ones might be the cause of my problem.
>
> Of course, all programmers have to adhere to the convention in order for

it
> to be useful. So to make a long story short, is it better to do
> this:
>
> void x::foo(A* a); // foo() will modify 'a'
> void x::bar(const A& a); // bar() will not modify 'a'
>
> Or is it better to do what my workplace requires?
>
> void x::foo(A& a); // foo() will modify 'a'
> void x::bar(const A& a); // bar() will not modify 'a'
>
> Am I wrong in suggesting the use of pointers for parameter-passing? Is
> there a reason why a reference should always be preferred over a pointer?
> My thinking is that this convention would make the C++ code more readable.
>
> ----
> Desmond
>
> (Remove the 'nospam' from the address for e-mail replies, but I prefer
> reply posts to the newsgroup)



 
Reply With Quote
 
Phlip
Guest
Posts: n/a
 
      07-26-2004
Dave Townsend wrote:

> In situations where an object may be passed or not, or may be present
> or not, a pointer is needed.


Read my post.

I think I might be able to extend the NullObject concept to say not using it
violates the Liskov Substitution Principle...

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces


 
Reply With Quote
 
Dave Townsend
Guest
Posts: n/a
 
      07-26-2004
Agreed, but using a NullObject only relates to new classes, not
legacy ones I have to live with.

"Phlip" <(E-Mail Removed)> wrote in message
newsdZMc.1890$(E-Mail Removed) ...
> Dave Townsend wrote:
>
> > In situations where an object may be passed or not, or may be present
> > or not, a pointer is needed.

>
> Read my post.
>
> I think I might be able to extend the NullObject concept to say not using

it
> violates the Liskov Substitution Principle...
>
> --
> Phlip
> http://industrialxp.org/community/bi...UserInterfaces
>
>



 
Reply With Quote
 
Phlip
Guest
Posts: n/a
 
      07-26-2004
Dave Townsend wrote:

> Agreed, but using a NullObject only relates to new classes, not
> legacy ones I have to live with.


Read /Working Effectively with Legacy Code/ by Mike Feathers.

Then think globally and act locally. One little NullObject at one interface
won't bring down the whole house of cards.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces


 
Reply With Quote
 
Desmond Liu
Guest
Posts: n/a
 
      07-26-2004
JKop <(E-Mail Removed)> wrote in news:zOWMc.5510$(E-Mail Removed):

> There are 2 and only 2 situations in which I choose a pointer over a
> reference:
>
> 1) When it must be re-seated
>
> 2) When arrays are involved
>
>
>> I understand the reasoning behind
>> using references--you avoid the cost of
>> creating a local object when you
>> pass an object by reference.

>
>
> Incorrect. The nature of today's computers (ie. stack and registers)
> still require a hidden pointer. (This is ofcourse where outline
> functions are involved).
>
>
> -JKop


Whoops. That was a typo. That should have read "avoid the cost of creating
a local object when you pass an object by _value_, as per Scott Meyer's
advice. Sorry.

Desmond
 
Reply With Quote
 
Joe C
Guest
Posts: n/a
 
      07-26-2004

"Phlip" <(E-Mail Removed)> wrote in message
news:MCXMc.120$(E-Mail Removed).. .
> C++ supports qualifications before their qualified types, such as "const
> SimCity &". I try to write expressions with the most important part first.
> There are also subtle technical reasons, in rare situations, to write
> "SimCity const &", with the const after its type.
>


Hi Phlip, can you elaborate on this? I've been using "const datatype &data"
rather than "datatype const &data". What are the differences between these
two semantic styles?




 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pointers, pointers, pointers... cerr C Programming 12 04-07-2011 11:17 PM
pointers to pointers question Chad C Programming 5 03-27-2006 07:44 AM
Need help with Style conversion from Style object to Style key/value collection. Ken Varn ASP .Net Building Controls 0 04-26-2004 07:06 PM
Style question, when to use pointers Karl C++ 2 12-30-2003 06:29 PM
Template specialization of pointers with function pointers Phil C++ 1 09-16-2003 02:17 AM



Advertisments