473,418 Members | 2,083 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,418 software developers and data experts.

Using pointer or reference?

Dear All,

The problem of choosing pointer or reference is always confusing me.
Would you please give me some suggestion on it. I appreciate your kind
help.

For example, I'd like to convert a string to a integer number.

bool Convert(const string& str, int* pData);
bool Convert(const string& str, int& data);

which one is better? Here bool is to show if the conversion is
successful.

Another example.

class Shape {};
class Sphere: public Shape {};
class Cube: public Shape {};

class Union: public Shape
{
private:
Shape* pShape1, pShape2;
// Or Shape& shape1, shape2;

public:
// Constructor.
Union(const Shape* pShape1, const Shape* pShape2); // or using
references
};

Shape* UnionOperation(const Shape* pShape1, const Shape* pShape2);
or
Shape& UnionOperation(const Shape& shape1, const Shape& shape2);
or
Shape* UnionOperation(const Shape& shape1, const Shape& shape2);

Thanks a lot!

Shuisheng

Dec 8 '06 #1
29 3614

shuisheng wrote:
Dear All,

The problem of choosing pointer or reference is always confusing me.
Would you please give me some suggestion on it.
Use reference unless you have to use a pointer for some reason.

Dec 8 '06 #2
shuisheng wrote:
The problem of choosing pointer or reference is always confusing me.
Would you please give me some suggestion on it. I appreciate your kind
help.

For example, I'd like to convert a string to a integer number.

bool Convert(const string& str, int* pData);
bool Convert(const string& str, int& data);

which one is better? Here bool is to show if the conversion is
successful.
Use the reference. You're going to provide an int no matter what,
right? So, why bother with the pointer? Pointers are only needed
if you for some reason might supply NULL (and the function would
have to check for it).
Another example.

class Shape {};
class Sphere: public Shape {};
class Cube: public Shape {};

class Union: public Shape
{
private:
Shape* pShape1, pShape2;
// Or Shape& shape1, shape2;

public:
// Constructor.
Union(const Shape* pShape1, const Shape* pShape2); // or using
references
References, unless you intend to potentially supply NULL as one or
both arguments.
};

Shape* UnionOperation(const Shape* pShape1, const Shape* pShape2);
or
Shape& UnionOperation(const Shape& shape1, const Shape& shape2);
or
Shape* UnionOperation(const Shape& shape1, const Shape& shape2);
Return an object, not a pointer or reference.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 8 '06 #3
shuisheng wrote:
Dear All,

The problem of choosing pointer or reference is always confusing me.
Would you please give me some suggestion on it. I appreciate your kind
help.

For example, I'd like to convert a string to a integer number.

bool Convert(const string& str, int* pData);
bool Convert(const string& str, int& data);

which one is better? Here bool is to show if the conversion is
successful.
There are two schools of thought on this. The "C++ way" is to use a
reference. It simplifiys the syntax a bit, makes it harder to pass a
completely bogus pointer, etc. However, there is a school of thought
that says that you should use pointers for "out" parameters, because
it's self-documenting *at the call sites* (without even looking at the
function signature) that the function could change the arguments. The
argument goes that if you see "foo(arg)", you can't tell whether foo
will change its argument, but if you see "foo(&arg)", you know it can.

I don't fully buy into this argument, but it's at least fairly widely
held. It's my suspicion that an argument somewhat along these lines is
why Java doesn't have pass-by-reference. C# solves this problem by
making you specify at call sites that something is being passed by
reference. For instance, if foo is declared as 'void foo(int ref a)',
when calling it you have to say 'foo(ref x)'. I think this is probably
a reasonable compromise, and might be better than either the C or the
C++ approach. I've somewhat taken up the habit of doing something
similar in C++ at call sites of functions that take reference
parameters to use them rather than const refs for speed, and write
foo(*& x). (This isn't always safe though.)

So I would summarize:

Arguments in favor of pointers:
- You can't pass by reference if you want it to be optional
- It's self-documenting at call-sites potential behavior of the
function

Arguments in favor of references:
- It does a slightly better job at enforcing that you give it a valid
object, because it decreases the amount you have to deal with pointers
at all
- The function itself is self-documenting that you must pass a valid
object, whereas you have to rely on either reading code or written
documentation to tell if you can pass a null pointer to a function that
takes pointers
- Somewhat cleaner syntax (IMO)
- It's the "C++ way"

In summary, I would go with what one of the other responses said, and
say use pointers if passing NULL makes sense for an optional parameter,
and use references if you have to be provided a valid object.

(Also note that if you're passing for efficiency -- you should
definitiely always use a const reference rather than a pointer to
const. Here you don't WANT to give the impression that it can be
modified, 'cause it can't.)
Another example.

class Shape {};
class Sphere: public Shape {};
class Cube: public Shape {};

class Union: public Shape
{
private:
Shape* pShape1, pShape2;
// Or Shape& shape1, shape2;

public:
// Constructor.
Union(const Shape* pShape1, const Shape* pShape2); // or using
references
This falls under my "passing for efficiency use references" rule I
think
};

Shape* UnionOperation(const Shape* pShape1, const Shape* pShape2);
or
Shape& UnionOperation(const Shape& shape1, const Shape& shape2);
or
Shape* UnionOperation(const Shape& shape1, const Shape& shape2);
Unless the UnionOperation is acting like a += operator and mutating one
of the elements then returning the new value, you almost hve to return
neither a reference nor a pointer. I can tell though that it's not
acting as that because both arguments are const.

It's very rare that you should return a reference. The only common
exceptions I can think of is containers returning references to
elements and smart pointers returning a reference to elements, if
that's how you want your smart pointer to work. (Even in the second
case, I don't know that I know all the implications of returning by
reference; it could be that that would cause subtle problems. Providing
access to the referent by pointer is more common.)

For instance, the following code:
int& foo() { int a; return a; }
is wrong, because the return value can never be accessed. (Automatic
storage goes away as soon as the function returns.

The same problem is in the following code:
int* foo() { int a; return &a; }
The pointer this returns is necessarily invalid.

To return a pointer or reference from a function, you need to refer to
data that it gets from somewhere else. A possibly incomplete list would
be:
-- For member functions of a class, data stored in the object (this
would be like the containers or function pointers)
-- Global data
-- Static data
-- Parameters (this is like most of the str___ functions from the std
library; they return one of the parameters passed in)
-- Heap allocated storage

The last one deserves more comment. You can write this:
int* foo() { return new int; }
or even this (I think):
int& foo() { return *(new int); }
but both are probably a bad idea at best.

In the first case, the caller of foo has to call delete on whatever
pointer is returned. This isn't enforced; it's just an implicit part of
the contract. And it's of course prone to forgetting to return, etc.
And finally you have to document what you need to use to delete it --
maybe the return from foo() was allocated with malloc, maybe new, maybe
some other allocator. And you have to pair the correct deallocation
routine. "Callee-allocated buffers" are non too uncommon, at least in C
code, so their use is not totally unresonable, but it's probably
usually better to ask the user to allocate a buffer and pass a pointer
or reference to it which the function can then fill in.

The second case is even worse because it's possible to write stuff like
"int x=foo();" where you don't even have to realize that you're dealing
with an int& return. Even if you did realize that, it's so non-standard
(I mean standard here not in the sense of ISO 14882 but just what is
used in practice) that it would totally throw anyone using it off.

Evan

Dec 8 '06 #4


On Dec 8, 7:19 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
shuisheng wrote:
The problem of choosing pointer or reference is always confusing me.
Would you please give me some suggestion on it. I appreciate your kind
help.
For example, I'd like to convert a string to a integer number.
bool Convert(const string& str, int* pData);
bool Convert(const string& str, int& data);
which one is better? Here bool is to show if the conversion is
successful.Use the reference. You're going to provide an int no matter what,
right? So, why bother with the pointer? Pointers are only needed
if you for some reason might supply NULL (and the function would
have to check for it).

You could even use a reference in that case by returning a NullObject.

Dec 8 '06 #5


On Dec 8, 7:52 pm, "Evan" <eva...@gmail.comwrote:
shuisheng wrote:
Dear All,
The problem of choosing pointer or reference is always confusing me.
Would you please give me some suggestion on it. I appreciate your kind
help.
For example, I'd like to convert a string to a integer number.
bool Convert(const string& str, int* pData);
bool Convert(const string& str, int& data);
which one is better? Here bool is to show if the conversion is
successful.There are two schools of thought on this. The "C++ way" is to use a
reference. It simplifiys the syntax a bit, makes it harder to pass a
completely bogus pointer, etc. However, there is a school of thought
that says that you should use pointers for "out" parameters, because
it's self-documenting *at the call sites* (without even looking at the
function signature) that the function could change the arguments. The
argument goes that if you see "foo(arg)", you can't tell whether foo
will change its argument, but if you see "foo(&arg)", you know it can.

I don't fully buy into this argument, but it's at least fairly widely
held. It's my suspicion that an argument somewhat along these lines is
why Java doesn't have pass-by-reference. C# solves this problem by
making you specify at call sites that something is being passed by
reference. For instance, if foo is declared as 'void foo(int ref a)',
when calling it you have to say 'foo(ref x)'. I think this is probably
a reasonable compromise, and might be better than either the C or the
C++ approach. I've somewhat taken up the habit of doing something
similar in C++ at call sites of functions that take reference
parameters to use them rather than const refs for speed, and write
foo(*& x). (This isn't always safe though.)

So I would summarize:

Arguments in favor of pointers:
- You can't pass by reference if you want it to be optional
You can, use the NullObject pattern

Andrew

Dec 8 '06 #6
"andrewmcdonagh" <an************@gmail.comwrote in
news:11**********************@n67g2000cwd.googlegr oups.com:
>

On Dec 8, 7:19 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>shuisheng wrote:
The problem of choosing pointer or reference is always confusing
me. Would you please give me some suggestion on it. I appreciate
your kind help.
For example, I'd like to convert a string to a integer number.
bool Convert(const string& str, int* pData);
bool Convert(const string& str, int& data);
which one is better? Here bool is to show if the conversion is
successful.Use the reference. You're going to provide an int no
matter what,
right? So, why bother with the pointer? Pointers are only needed
if you for some reason might supply NULL (and the function would
have to check for it).


You could even use a reference in that case by returning a NullObject.

If that's possible. Not appropriate for ints.
Dec 8 '06 #7

"Evan" <ev****@gmail.comwrote in message
news:11**********************@79g2000cws.googlegro ups.com...
shuisheng wrote:
>Dear All,

The problem of choosing pointer or reference is always confusing me.
Would you please give me some suggestion on it. I appreciate your kind
help.

For example, I'd like to convert a string to a integer number.

bool Convert(const string& str, int* pData);
bool Convert(const string& str, int& data);

which one is better? Here bool is to show if the conversion is
successful.

There are two schools of thought on this. The "C++ way" is to use a
reference. It simplifiys the syntax a bit, makes it harder to pass a
completely bogus pointer, etc. However, there is a school of thought
that says that you should use pointers for "out" parameters, because
it's self-documenting *at the call sites* (without even looking at the
function signature) that the function could change the arguments. The
argument goes that if you see "foo(arg)", you can't tell whether foo
will change its argument, but if you see "foo(&arg)", you know it can.
[snip]

Evan-

Consider: void foo(int const *arg);

foo(&arg) sort of implies arg can be changed but certainly doesn't prove it.

OP-

The problem I have with pointers is that people may think they are supposed
to delete them when they are done. However, even using references can't
prevent that:

void dumb_implementation(Fred &f) {
delete &Fred; // ugh
}
I know that looks horrible but I have seen it done.

Overall I would say stick with references unless you have a pretty good
reason (need to test for NULL, legacy, C interface, etc.)

Cy
Dec 9 '06 #8

Cy Edmunds wrote:
Evan-

Consider: void foo(int const *arg);

foo(&arg) sort of implies arg can be changed but certainly doesn't prove it.
Oh, I know. This is one reason why I don't really buy the "pointers are
useful because they are somewhat self-documenting" argument. Just
because you pass by pointer doesn't mean that the function is using it
as an out parameter.

Evan

Dec 9 '06 #9
shuisheng wrote:
>
Dear All,

The problem of choosing pointer or reference is always confusing me.
Would you please give me some suggestion on it. I appreciate your kind
help.

For example, I'd like to convert a string to a integer number.

bool Convert(const string& str, int* pData);
bool Convert(const string& str, int& data);
or
bool Convert( const string* str, int* pData );
bool Convert( const string* str, int& pData );
>
which one is better? Here bool is to show if the conversion is
successful.
First, let's review why references were added to the language. The only
reason they were added was to support operator overloading. In those
instances you must use a reference. In any other situation, if you can
use a reference, you could also use a pointer.

In Even's post, he discussed a common heard argument about using
pointers for output parameters. However, the argument is bogus:

int i;
foo( &i );

Without seeing the declaration of 'foo' you simply can't know if it can
modify the value of 'i'. (foo may take a const int*.)

So, you *could* just always use a pointer in every case (except in
op-overloads) and you would be fine. Personally, I prefer using this as
an opportunity to help document the code. So here is my algorithm for
deciding:

if passing in a C array, use a pointer.
else if the function is an opperator overload, use a reference.
else if the caller can destroy the parameter immediatly after the
function returns, use a reference.
else if the caller cannot destroy the parameter immediatly after the
function returns, use a pointer.
else if the function would work fine with parameters passed by value
but the sizeof the parameter is greater than sizeof int, use a const
reference.
else Pass by value.

I think that's about it.

So in your example above, the function would work fine with the 'str'
passed in by value, but the sizeof string is greater than sizeof int,
so pass 'str' by const reference. The caller can destroy the second
parameter immediatly after the function returns (by deleting or forcing
the parameter out of scope) so use a reference. i.e.,

bool Convert( const string& str, int& data );
Another example.

class Shape {};
class Sphere: public Shape {};
class Cube: public Shape {};

class Union: public Shape
{
private:
Shape* pShape1, pShape2;
// Or Shape& shape1, shape2;
I can't think of the last time I used a reference as member-data.
public:
// Constructor.
Union(const Shape* pShape1, const Shape* pShape2); // or using
references
};
If the two objects passed in are going to be assigned to the two
member-variables, then the caller cannot destroy them immediatly after
the object is constructed (without leaving the object with a couple of
invalid pointers,) so I would use Shape*. BTW, in the situation I
describe, they could not be const pointers, because the
member-variables aren't const.
Shape* UnionOperation(const Shape* pShape1, const Shape* pShape2);
or
Shape& UnionOperation(const Shape& shape1, const Shape& shape2);
or
Shape* UnionOperation(const Shape& shape1, const Shape& shape2);
For return values:
if the function returns an array and the caller isn't supposed to
destroy the array, return by const pointer.
else if the function returns an array and the caller is supposed to
destroy the array, return by pointer.
else if the caller is supposed to destroy the object returned, return a
pointer.
else if the function would work just fine if it returned by value, but
sizeof the return type is greater than sizeof int, return by const
reference.
else if the caller is supposed to be able to modify the value returned,
return by reference (this should be very rare IMHO.)
else return by value.

Which of the above three "UnionOperation"s is approprate depends on
what the function does with the parameters.

Dec 9 '06 #10

shuisheng wrote:
Dear All,

The problem of choosing pointer or reference is always confusing me.
Would you please give me some suggestion on it. I appreciate your kind
help.
Here is an attempt at a simpler list:

1) Use pointers if you may need to move to additional locations offset
from the address.
2) Use pointers if setting the pointer to 0 will indicate something
back to the caller
3) Use references if you want to protect against possibly derencing a
null pointer and core dumping

otherwise, use either.

-
Ivan
http://www.0x4849.net

Dec 9 '06 #11

"Daniel T." <da******@earthlink.netwrote in message
news:11**********************@73g2000cwn.googlegro ups.com...
In Even's post, he discussed a common heard argument about using
pointers for output parameters. However, the argument is bogus:

int i;
foo( &i );

Without seeing the declaration of 'foo' you simply can't know if it can
modify the value of 'i'. (foo may take a const int*.)
How often do you use functions without looking at the
declaration?

This is actually more of a problem when using pointers.

foo(int *i) {
*i = new int;
}

Just looking at the declaration doesn't help much.
Dec 9 '06 #12

"Ivan Novick" <iv**@0x4849.netwrote in message
news:11**********************@j44g2000cwa.googlegr oups.com...
Here is an attempt at a simpler list:

1) Use pointers if you may need to move to additional locations offset
from the address.
2) Use pointers if setting the pointer to 0 will indicate something
back to the caller
3) Use references if you want to protect against possibly derencing a
null pointer and core dumping

otherwise, use either.
I prefer Stroustrup's advice. Use a reference
when you can. Use a pointer when you have to.
Dec 9 '06 #13

Duane Hebert wrote:
"Daniel T." <da******@earthlink.netwrote in message
news:11**********************@73g2000cwn.googlegro ups.com...
In Even's post, he discussed a common heard argument about using
pointers for output parameters. However, the argument is bogus:

int i;
foo( &i );

Without seeing the declaration of 'foo' you simply can't know if it can
modify the value of 'i'. (foo may take a const int*.)

How often do you use functions without looking at the
declaration?

This is actually more of a problem when using pointers.

foo(int *i) {
*i = new int;
}
i = new int; you mean. ;-)
But to answer your question, I think the argument goes that it doesn't
help much when you're WRITING the code, but if you're thrown into some
system you probably don't want to check the signature of every function
that's used. (Especially if you're using an editor without good code
browsing abilities (right click, got to declaration).) Ideally then if
you see a call "foo(x)" you'd like to know at the call site if x could
change or if foo's a pure function. Even C falls flat on its face in
this regard, so I don't think that references hurt it too much.

Evan

Dec 9 '06 #14
Duane Hebert wrote:
"Daniel T." <da******@earthlink.netwrote:
>In Even's post, he discussed a common heard argument about using
pointers for output parameters. However, the argument is bogus:

int i;
foo( &i );

Without seeing the declaration of 'foo' you simply can't know if it
can modify the value of 'i'. (foo may take a const int*.)

How often do you use functions without looking at the declaration?
Never and that's the point.
This is actually more of a problem when using pointers.

foo(int *i) {
*i = new int;
}

Just looking at the declaration doesn't help much.
The above doesn't compile and:

void foo( int* i ) {
i = new int;
}

Doesn't affect the calling code at all. You might want to re-think what
you are trying to get at.

Dec 9 '06 #15

Evan wrote:
Duane Hebert wrote:
"Daniel T." <da******@earthlink.netwrote in message
news:11**********************@73g2000cwn.googlegro ups.com...
In Even's post, he discussed a common heard argument about using
pointers for output parameters. However, the argument is bogus:
>
int i;
foo( &i );
>
Without seeing the declaration of 'foo' you simply can't know if it can
modify the value of 'i'. (foo may take a const int*.)
How often do you use functions without looking at the
declaration?
But to answer your question, I think the argument goes that it doesn't
help much when you're WRITING the code, but if you're thrown into some
system you probably don't want to check the signature of every function
that's used. (Especially if you're using an editor without good code
browsing abilities (right click, got to declaration).) Ideally then if
you see a call "foo(x)" you'd like to know at the call site if x could
change or if foo's a pure function. Even C falls flat on its face in
this regard, so I don't think that references hurt it too much.
As well as the pointer to const data example making the argument bogus,
there is also the fact that in the real world, functions are not called
"foo(x)", they are called things like "cosine(x)" or "increment(x)" and
the name itself should give a strong indication as to whether the
parameter is modified or not.

Even given a meaningful function name, you still cannot *know* whether
the parameter is modified or not. Only the interface documentation can
ever tell you that. But if meaningful names are used, the problem of
interpreting the code when all you see is the call site is not as hard
as it might appear to be from an example that only uses abstract names
like foo and bar for the function.

Gavin Deane

Dec 9 '06 #16
Duane Hebert wrote:
"Ivan Novick" <iv**@0x4849.netwrote:
>Here is an attempt at a simpler list:

1) Use pointers if you may need to move to additional locations
offset from the address.
2) Use pointers if setting the pointer to 0 will indicate something
back to the caller
3) Use references if you want to protect against possibly derencing
a null pointer and core dumping

otherwise, use either.

I prefer Stroustrup's advice. Use a reference when you can. Use a
pointer when you have to.
Hmm, AFAIK the only time you must use a pointer is if you are passing
an array. What about passing by value?

Dec 9 '06 #17

"Daniel T." <da******@earthlink.netwrote in message
news:11**********************@79g2000cws.googlegro ups.com...
>>Without seeing the declaration of 'foo' you simply can't know if it
can modify the value of 'i'. (foo may take a const int*.)

How often do you use functions without looking at the declaration?

Never and that's the point.
>This is actually more of a problem when using pointers.

foo(int *i) {
*i = new int;
should be i = new int;
>}

Just looking at the declaration doesn't help much.

The above doesn't compile and:

void foo( int* i ) {
i = new int;
}

Doesn't affect the calling code at all. You might want to re-think what
you are trying to get at.
You seem to be saying to prefer pointers over references
because with references you can't know if the variable is
going to be modified by the function. Sorry if I didn't get
your point then...
Dec 10 '06 #18

"Gavin Deane" <de*********@hotmail.comwrote in message
news:11*********************@80g2000cwy.googlegrou ps.com...
>
Evan wrote:
>Duane Hebert wrote:
"Daniel T." <da******@earthlink.netwrote in message
news:11**********************@73g2000cwn.googlegro ups.com...

In Even's post, he discussed a common heard argument about using
pointers for output parameters. However, the argument is bogus:

int i;
foo( &i );

Without seeing the declaration of 'foo' you simply can't know if it
can
modify the value of 'i'. (foo may take a const int*.)

How often do you use functions without looking at the
declaration?
But to answer your question, I think the argument goes that it doesn't
help much when you're WRITING the code, but if you're thrown into some
system you probably don't want to check the signature of every function
that's used. (Especially if you're using an editor without good code
browsing abilities (right click, got to declaration).) Ideally then if
you see a call "foo(x)" you'd like to know at the call site if x could
change or if foo's a pure function. Even C falls flat on its face in
this regard, so I don't think that references hurt it too much.

As well as the pointer to const data example making the argument bogus,
there is also the fact that in the real world, functions are not called
"foo(x)", they are called things like "cosine(x)" or "increment(x)" and
the name itself should give a strong indication as to whether the
parameter is modified or not.

Even given a meaningful function name, you still cannot *know* whether
the parameter is modified or not. Only the interface documentation can
ever tell you that. But if meaningful names are used, the problem of
interpreting the code when all you see is the call site is not as hard
as it might appear to be from an example that only uses abstract names
like foo and bar for the function.
Well that's sort of my point. You need to know what the function
is doing when you call it. Making the arg a pointer doesn't change
this. My other point is that it's actually clearer without using
pointers. If it's a copy, it doesn't matter. If it's a const & it won't
be modified. If it's a non const &, just assume that it will be or
look at the documentation.
Dec 10 '06 #19

"Evan" <ev****@gmail.comwrote in message
news:11**********************@16g2000cwy.googlegro ups.com...
>
Duane Hebert wrote:
>"Daniel T." <da******@earthlink.netwrote in message
news:11**********************@73g2000cwn.googlegr oups.com...
In Even's post, he discussed a common heard argument about using
pointers for output parameters. However, the argument is bogus:

int i;
foo( &i );

Without seeing the declaration of 'foo' you simply can't know if it can
modify the value of 'i'. (foo may take a const int*.)

How often do you use functions without looking at the
declaration?

This is actually more of a problem when using pointers.

foo(int *i) {
*i = new int;
}

i = new int; you mean. ;-)
But to answer your question, I think the argument goes that it doesn't
help much when you're WRITING the code, but if you're thrown into some
system you probably don't want to check the signature of every function
that's used. (Especially if you're using an editor without good code
browsing abilities (right click, got to declaration).) Ideally then if
you see a call "foo(x)" you'd like to know at the call site if x could
change or if foo's a pure function. Even C falls flat on its face in
this regard, so I don't think that references hurt it too much.
OK. Now I get get what Daniel is saying. I thought he
was arguing that using pointers somehow solved this.
No, in this respect I don't see that it matters.
Sorry for wasting the bandwidth.
Dec 10 '06 #20

"Daniel T." <da******@earthlink.netwrote in message
news:11**********************@j44g2000cwa.googlegr oups.com...
Duane Hebert wrote:
>"Ivan Novick" <iv**@0x4849.netwrote:
>>Here is an attempt at a simpler list:

1) Use pointers if you may need to move to additional locations
offset from the address.
2) Use pointers if setting the pointer to 0 will indicate something
back to the caller
3) Use references if you want to protect against possibly derencing
a null pointer and core dumping

otherwise, use either.

I prefer Stroustrup's advice. Use a reference when you can. Use a
pointer when you have to.

Hmm, AFAIK the only time you must use a pointer is if you are passing
an array. What about passing by value?
When passing by value, the variable can't be modified. I think
I've missed your point. As for when you need a pointer, you need
it if it can be null. You also need it when you want to reassign it.
Dec 10 '06 #21
Duane Hebert wrote:
"Daniel T." <da******@earthlink.netwrote:
>Duane Hebert wrote:
>>"Ivan Novick" <iv**@0x4849.netwrote:

Here is an attempt at a simpler list:

1) Use pointers if you may need to move to additional locations
offset from the address. 2) Use pointers if setting the pointer
to 0 will indicate something back to the caller 3) Use references
if you want to protect against possibly derencing a null pointer
and core dumping

otherwise, use either.

I prefer Stroustrup's advice. Use a reference when you can. Use a
pointer when you have to.

Hmm, AFAIK the only time you must use a pointer is if you are
passing an array. What about passing by value?

When passing by value, the variable can't be modified.
And when passing by const reference the value can't be modified so do
you never pass by value?

"Use reference when you can, use pointers when you must" doesn't cover
when you should pass by value.
As for when you need a pointer, you need it if it can be null.
You can always redesign the function so that passing a null is
invalid/undefined.
You also need it when you want to reassign it.
You can do that with references:

void fn( int& i ) {
i = 65;
}

Dec 10 '06 #22
Duane Hebert wrote:
"Daniel T." <da******@earthlink.netwrote:
>>
void foo( int* i ) {
i = new int;
}

Doesn't affect the calling code at all. You might want to re-think
what you are trying to get at.

You seem to be saying to prefer pointers over references because
with references you can't know if the variable is going to be
modified by the function. Sorry if I didn't get your point then...
I'm saying that in any case where you can use a reference (except
operator overloads) you can use a pointer. Prefer whichever you want,
but it is merely preference, there is no compelling reason to use one
over the other.

My own preference is to use them as a documentation tool. I use a
pointer if the calling code can't destroy the object immediatly upon
exit of the function, and a reference if it can.

Dec 10 '06 #23

"Daniel T." <da******@earthlink.netwrote in message
news:11*********************@73g2000cwn.googlegrou ps.com...
>When passing by value, the variable can't be modified.

And when passing by const reference the value can't be modified so do
you never pass by value?
I usually pass by value when I want to give the function
a copy of the value and it's not large. Passing an int
by non const reference makes no sense to me. Nor does passing
a vector by value instead of const reference.

"Use reference when you can, use pointers when you must" doesn't cover
when you should pass by value.
When should you pass by value except when it's more efficient
than a const & ?
>As for when you need a pointer, you need it if it can be null.

You can always redesign the function so that passing a null is
invalid/undefined.
If it's your function.
>You also need it when you want to reassign it.

You can do that with references:

void fn( int& i ) {
i = 65;
}
This is not what I mean. Perhaps I should have
said reseating or something.
Dec 10 '06 #24

"Duane Hebert" <sp**@flarn2.comwrote in message
news:Ys*******************@wagner.videotron.net...
>
"Daniel T." <da******@earthlink.netwrote in message
news:11*********************@73g2000cwn.googlegrou ps.com...
>>When passing by value, the variable can't be modified.

And when passing by const reference the value can't be modified so do
you never pass by value?

I usually pass by value when I want to give the function
a copy of the value and it's not large. Passing an int
by non const reference makes no sense to me. Nor does passing
That should be "passing an int by const & makes no sense to me. "
Dec 10 '06 #25
Duane Hebert wrote:
"Daniel T." <da******@earthlink.netwrote:
>>When passing by value, the variable can't be modified.

And when passing by const reference the value can't be modified so
do you never pass by value?

I usually pass by value when I want to give the function a copy of
the value and it's not large. Passing an int by non const reference
makes no sense to me. Nor does passing a vector by value instead of
const reference.
>"Use reference when you can, use pointers when you must" doesn't
cover when you should pass by value.

When should you pass by value except when it's more efficient than a
const & ?
OK, so add that to the formulation. That's all I'm saying here, the
quote you provided doesn't tell the whole story because you can use
references even where passing by value makes more sense.
>>As for when you need a pointer, you need it if it can be null.

You can always redesign the function so that passing a null is
invalid/undefined.

If it's your function.
If it isn't our function, then we aren't going to be making any
decisions about what the parameter types are. The discussion assumes we
are the one's making the decision, so of course it's our function.
>>You also need it when you want to reassign it.

You can do that with references:

void fn( int& i ) {
i = 65;
}

This is not what I mean. Perhaps I should have said reseating or
something.
Reseating a pointer within a function has no effect on the calling
function either. Your previous example, as I pointed out, was
pointless.

When designing a function, we can make the parameter type T, const T&,
T&, const T*, or T*. The OP asked how to decide between the five
options. I'm interested in your answer. How do you decide between them?
Can your formulate your decision process as an algorithm?

Dec 10 '06 #26

"Daniel T." <da******@earthlink.netwrote in message
news:11**********************@16g2000cwy.googlegro ups.com...
OK, so add that to the formulation. That's all I'm saying here, the
quote you provided doesn't tell the whole story because you can use
references even where passing by value makes more sense.
Your example of passing &i is what caught my attention. I just
had to clean up a bunch of code written by a former employee.
He decided to write functions that took a std::vector*. When he
called these functions, if he had a std::vector, he passed it
by &vec. He didn't like iterators.

>>>As for when you need a pointer, you need it if it can be null.

You can always redesign the function so that passing a null is
invalid/undefined.

If it's your function.

If it isn't our function, then we aren't going to be making any
decisions about what the parameter types are. The discussion assumes we
are the one's making the decision, so of course it's our function.
>>>You also need it when you want to reassign it.

You can do that with references:

void fn( int& i ) {
i = 65;
}

This is not what I mean. Perhaps I should have said reseating or
something.

Reseating a pointer within a function has no effect on the calling
function either. Your previous example, as I pointed out, was
pointless.
Well you can dereference a pointer and do pretty much
what you want with it.
When designing a function, we can make the parameter type T, const T&,
T&, const T*, or T*. The OP asked how to decide between the five
options. I'm interested in your answer. How do you decide between them?
Can your formulate your decision process as an algorithm?
Not really as an algorithm. It would be nice if you could
create algorithms to tell you how to design software
on this level but it would be hard to cover all the possibilities.

Sometimes you need to use pointers. For
example, if you use Borland's VCL, all of their TObject stuff must
be pointers. With Qt, it's often the case though not exclusively.

When you write functions, you don't always get to choose the
types that you're working with.

But given generic code, assuming that I don't want to modify
the variable, if it's no more efficient to use a reference, I would
just pass it by value.

If the object is expensive to copy like a vector<spoo>, I would
use const &.

Beyond that, it depends on the circumstances.
Dec 10 '06 #27
Daniel T. wrote:
Duane Hebert wrote:
"Daniel T." <da******@earthlink.netwrote:
When designing a function, we can make the parameter type T, const T&,
T&, const T*, or T*. The OP asked how to decide between the five
options. I'm interested in your answer. How do you decide between them?
Can your formulate your decision process as an algorithm?
Hmm, here's my thoughts... not sure if I follow this exactly myself,
but I'll give it a shot.

if( there does not need to be a way to express "no value" )
{
if( parameter is just an in parameter )
{
if( the type is sufficiently small so the overhead of
copying is less than the overhead of accessing
it through a pointer)
{
pass by value
}
else
{
if( the function is C++ only)
pass by const reference
else // it needs to be callable from C
pass by const pointer
}
}
else
{ // parameter is out or inout
if( the function is C++ only )
pass by reference
else
pass by pointer
}
}
else
{ // there needs to be a way to express "no value"
if( parameter is an in parameter )
pass by const pointer
else
pass by pointer
}

Wow, that's actually pretty complicated...

Dec 10 '06 #28

"Evan" <ev****@gmail.comwrote in message
news:11**********************@80g2000cwy.googlegro ups.com...
Daniel T. wrote:
>Duane Hebert wrote:
"Daniel T." <da******@earthlink.netwrote:
>When designing a function, we can make the parameter type T, const T&,
T&, const T*, or T*. The OP asked how to decide between the five
options. I'm interested in your answer. How do you decide between them?
Can your formulate your decision process as an algorithm?

Hmm, here's my thoughts... not sure if I follow this exactly myself,
but I'll give it a shot.

if( there does not need to be a way to express "no value" )
{
if( parameter is just an in parameter )
{
if( the type is sufficiently small so the overhead of
copying is less than the overhead of accessing
it through a pointer)
{
pass by value
}
else
{
if( the function is C++ only)
pass by const reference
else // it needs to be callable from C
pass by const pointer
}
}
else
{ // parameter is out or inout
if( the function is C++ only )
pass by reference
else
pass by pointer
}
}
else
{ // there needs to be a way to express "no value"
if( parameter is an in parameter )
pass by const pointer
else
pass by pointer
}

Wow, that's actually pretty complicated...
Yeah but it covers most options. It's
about the way that I look at it as well.
Dec 10 '06 #29
Evan wrote:
Daniel T. wrote:
>Duane Hebert wrote:
>>"Daniel T." <da******@earthlink.netwrote:
>When designing a function, we can make the parameter type T, const
T&, T&, const T*, or T*. The OP asked how to decide between the
five options. I'm interested in your answer. How do you decide
between them? Can your formulate your decision process as an
algorithm?

Hmm, here's my thoughts... not sure if I follow this exactly myself,
but I'll give it a shot.

if( there does not need to be a way to express "no value" )
{
if( parameter is just an in parameter )
{
if( the type is sufficiently small so the overhead of
copying is less than the overhead of accessing
it through a pointer)
{
pass by value
}
else
{
if( the function is C++ only)
pass by const reference
else // it needs to be callable from C
pass by const pointer
}
}
else
{ // parameter is out or inout
if( the function is C++ only )
pass by reference
else
pass by pointer
}
}
else
{ // there needs to be a way to express "no value"
if( parameter is an in parameter )
pass by const pointer
else
pass by pointer
}

Wow, that's actually pretty complicated...
Well then, let's refactor it.

(a) The first 'if' can be summarily decided as 'false'. There is no
compelling reason to allow the caller to express "no value".

(b) Since this is a C++ forum, let's assume C++ throughout.

So it becomes:

if ( in parameter only )
if ( sizeof parameter <= sizeof int )
pass by value
else
pass by const reference
else
pass by reference

Hmm...

One thing it misses is what to do if the parameter is supposed to
represent an array, but if one consistently uses 'vector' for arrays,
that removes it as a need.

So you only pass by pointer if the function needs to be callable from C
or if you choose to allow the caller to pass in NULL. Is that correct?

Dec 11 '06 #30

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Ireneusz SZCZESNIAK | last post by:
I want to sort a vector with the std::sort function. There are two functions: one with two arguments, the other with three arguments. I am using the one with three arguments. I noticed that...
11
by: Doug | last post by:
Is there any harm in passing an object into a method with the 'ref' keyword if the object is already a reference variable? If not, is there any benefit?
0
by: Lokkju | last post by:
I am pretty much lost here - I am trying to create a managed c++ wrapper for this dll, so that I can use it from c#/vb.net, however, it does not conform to any standard style of coding I have seen....
3
by: Miguel | last post by:
Hi, I'm new to .NET and am using VB .NET as I am from a VB background. I am having difficulty understanding the way .NET handles, passes and uses objects. I have had a look at the Micrsoft Data...
6
by: semkaa | last post by:
Can you explain why using ref keyword for passing parameters works slower that passing parameters by values itself. I wrote 2 examples to test it: //using ref static void Main(string args) {...
10
by: Jess | last post by:
Hello, If I create a temporary object using a dynamically created object's pointer, then when the temporary object is destroyed, will the dynamically created object be destroyed too? My guess...
41
by: Summercool | last post by:
Can we confirm the following? also someone said, Java also has "reference" like in C++, which is an "implicit pointer": Pointer and Reference --------------------- I am starting to see what...
68
by: Jim Langston | last post by:
I remember there was a thread a while back that was talking about using the return value of a function as a reference where I had thought the reference would become invalidated because it was a...
65
by: Arjen | last post by:
Hi, Form a performance perspective, is it wise to use the ref statement as much as possible? Thanks! Arjen
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.