Archived

This topic is now archived and is closed to further replies.

Tazel

&

Recommended Posts

What is the difference between these two functions? void foo& function(int arg, int arg) and void foo function(int& arg, int& arg) and void foo& function(int& arg, int& arg) Tell me if what I think is right. The first one tells you to return a reference to a type foo (probably an object). Does this mean if it did not have it, whatever variable was initialized to that function would be copied, and then returned which wouldn''t do anything? The 2nd one, it passes reference variables so that you can change the actual value of the variables. What''s the difference with doing this with a pointer? I''ve seen not many people use pointers to pass arguments except when using the double pointers. The third one returns a foo type and passes two arguments with reference so they can be changed. Now if this is all right, I''m still not sure when to use what. Except the passsing the reference arguments. I''m not fully understanding what the foo& function () still does. Thanks to anyone who takes the time to read this and help me out!
tcache Contact Me ----------- AH! MY BRAIN IS GOING TO SELF-DETONATE! -- Yours Truly (Jan, 2003)

Share this post


Link to post
Share on other sites
Hi Tazel

There is one main difference between passing by reference and passing by pointer: You can't really have a null reference (you can but as I'll explain later it's bad news if you do).

null pointers are used for all kinds of things. Often they are a way of communicating that you don't need the value that the function would normally fill in for you in the object pointed to by the non-null pointer. The function either has to check for the null before writing to it or assume that it will never be passed a null pointer. This can lead to bugs.

Using references avoids this potential for errors. Now you might say you actually want to communicate in this way (ie passing a null). An alternative is to create null versions of your objects (you can't do this for ints and other built in types, so it's limited, but still useful).

Ie if you have a Dog class you could also have a nullDog class, derived from the same base. This can be passed around in places where you would normally have a null pointer but can't because you're using references to increase safety. This is quite an advanced technique but worth mentioning, I feel.

Note:
To get a null reference you would have to dereference a null pointer, which isn't allowed anyway and leads to undefined behaviour. It might crash, it might not. If you're lucky it will crash.

eg
void someFunction(int& r);

int* pInt = 0;
int& rInt = *pInt;//dereferencing a null pointer, might crash!
someFunction(rInt);// bad news

edit: c doesn't have pass by reference - it's a c++ thing

[edited by - petewood on January 18, 2003 11:19:19 AM]

Share this post


Link to post
Share on other sites
Don't use reference as a replacement to pointers, they are alot more confusing. They have their purpose with operator overloading and container classes, but not with normal function arguments. My first rule-of-thumb is to never use reference on basic types.

If I see this is a piece of code:

int a = 10;
some_function(a);

I, for one, will (correctly IMHO) assume that a is passed by value . Now, when people (ab)use reference, I must go lookup the function declaration/definition to be sure. When you use regular pointers, you are more explicit about what you're doing (which is A Good Thing™ ).




[edited by - CWizard on January 18, 2003 11:26:29 AM]

Share this post


Link to post
Share on other sites
I thought I''d add some more - answer your questions more than going off in my own little world.

quote:
I''m still not sure when to use what


Okay, the main reason for passing things by pointers or references is if the objects are large. By large I mean larger than the built in types. Compilers can cope fine with passing ints, doubles, bools etc. Passing these by reference is a waste of time if the value isn''t going to be changed by the function. If the value needs to be changed then pass it by reference.

If the value isn''t going to be changed then pass built in types by value (ints etc) like in the arguments of your first function.

If the value is an object of user defined type then pass it by reference.

There is then a danger or at least an uncertainty about whether the function will change the value or not. To indicate this have the function use the ''const'' keyword indicate that it won''t change it.

ie
void someFunction(const int& arg1, int& arg2);// yeah your code is a little wrong using arg twice

This should be taken to mean the function can''t change the first argument and will change the second.

As I said in the previous post, I prefer not to use pointers. I only use them for purely C interfaces.

Share this post


Link to post
Share on other sites
quote:
int a = 10;
some_function(a);

I, for one, will (correctly IMHO) assume that a is passed by value


Er... passing by reference is widely used.

If the function had a more realistic name such as

void getWidthAndHeight(int& width, int& height);

Looking at code like that below, would you assume that width and height aren''t being modified?
int width, height;
getWidthAndHeight(width, height);

The names you give functions are important to communicate to people how they should be used. I think your point is bogus (IMHO)

Share this post


Link to post
Share on other sites
I agree with petewood. If you give your functions and parameters meaningful names, then using references is not a problem. (In my humble opinion anyway. I''m not a professional programmer, so perhaps I''m a bit naive)

Personally I prefer references over pointers wherever it is practical. I like the increased safety. I''ve found it''s a lot easier for bugs to creep in when you''re using pointers. I still use pointers in situations where I feel it is better/simpler, such as the NULL pointer example given.

Share this post


Link to post
Share on other sites
quote:
Original post by petewood
Looking at code like that below, would you assume that width and height aren''t being modified?
int width, height;
getWidthAndHeight(width, height);
Of course I would come to the conclusion that they are passed by reference. But, it does cloud what''s going on.
GetDimension(&width, &height);
Is more explicit, and more natural to my mind. As what I do is passing the address of the variable and not it''s value. In the rest of the language, a plain variable evaluates to it''s value, and so I think the reference syntax is somewhat inconsistent with the rest. I recognize references to be a complementary part of the C++ language, but I see no reasons to use them where pointers do good.

In the end, I think references and pointers are conflicting in a language; use one or the other.


Share this post


Link to post
Share on other sites
quote:
Original post by Oxyacetylene
Personally I prefer references over pointers wherever it is practical. I like the increased safety. I''ve found it''s a lot easier for bugs to creep in when you''re using pointers.
Out of curiosity, in what way are references more safe than pointers? Unless you do nasty casts (which you can do with references as well), which you shouldn''t, I can''t see what''s safer with references.


Share this post


Link to post
Share on other sites
quote:
in what way are references more safe than pointers


As i''ve already said, you shouldn''t ever get a null reference unless you or the people using your code are incompetant, but I''ll assume they know better than dereferencing a pointer without checking it. It puts the testing for null outside of the function, if necessary.

Share this post


Link to post
Share on other sites
I thought the reason you used references over pointers was that they save you from explicitly dereferencing. You can pass them just as if you are passing by value and within a function you can treat them as if they had been passed by value. I try to only pass pointers if I intend to modify the pointer itself. The const keyword should save you from passing something which you do not want modified.

Share this post


Link to post
Share on other sites
quote:
Original post by CWizard
Out of curiosity, in what way are references more safe than pointers? Unless you do nasty casts (which you can do with references as well), which you shouldn''t, I can''t see what''s safer with references.



I just find I''m less likely to end up passing a NULL pointer, or an invalid pointer to a function if I use references.

Sure, you could dereference an invalid pointer, and pass it as a reference, but I find I''m a lot less likely to do that.

Of course if a function doesn''t want a NULL pointer, I can always use an assert to catch it, but why bother when I can use references? What if I forget to put the assert in?

Here''s an example of the kind of thing I''ve done when I''ve not been quite on the ball.


  
CObject* object; //forgot to initialise pointer

DoSomethingWithObject( object ); //BANG



Now sure, if you''re careful that won''t happen, but I find it''s easy to make a mistake when you''ve been programming for hours.

I don''t see any ambiguity in a function call that uses references, but that''s probably because my first experience of C/C++, was with C++. We were taught to use references before we even learned what a pointer was. I''m used to references, I didn''t even use C until I did Playstation programming in my 4th year of uni. (Codewarrior bad)

Share this post


Link to post
Share on other sites
quote:
Original post by Oxyacetylene
CObject* object; //forgot to initialise pointer
DoSomethingWithObject( object ); //BANG


How does references save you in this case? I usually don't use reference in this way, but you would need to:

void DoSomethingWithObject(CObject &object);

CObject *object;
// You need to do this
DoSomethingWithObject(*object);
// As this would be to pass a reference to CObject pointer (ie. type error)
DoSomethingWithObject(object);

And same error would occur as with a wild pointer, or...?

In either case, the compiler throws a warning in your face, so it isn't easy to miss.

EDIT: If object wasn't a pointer, but the object itself, there's no risk of it not being initialized.

Btw, I sometimes use references when passing certain types of objects, but never with basic types.




[edited by - CWizard on January 18, 2003 2:13:46 PM]

Share this post


Link to post
Share on other sites
quote:
CObject *object;
// You need to do this
DoSomethingWithObject(*object);

You''re the one dereferencing the invalid pointer and you can choose not to, therefore it''s safer. It puts the responsibility in your hands. However, what you''ll find is you can pretty much do away with pointers if you use references everywhere. As I said, you only really need pointers for pure C apis. So all this talk about checking will only occur at the api interface. Once you''ve established that the pointer is non-null you can proceed without any conditional stuff. If the pointer is null you can replace it with a null object, as I''ve described and again benefit from simpler code.

Pete

Share this post


Link to post
Share on other sites
quote:
Original post by petewood
You''re the one dereferencing the invalid pointer and you can choose not to, therefore it''s safer. It puts the responsibility in your hands.
I can''t make any sense of that. The context was the claim that references could save you from unitialized pointers. How am I supposed to pass an object to a function that expects a reference without dereferencing the pointer to the object?
quote:
However, what you''ll find is you can pretty much do away with pointers if you use references everywhere.
Yes, in most cases, but the question is why? A reference is a pointer, why obscure that fact?
quote:
As I said, you only really need pointers for pure C apis.
Huh? How do you replace pointer arithmetic with references?


Share this post


Link to post
Share on other sites
quote:
How am I supposed to pass an object to a function that expects a reference without dereferencing the pointer to the object?

Exactly, you have to ensure that the object you pass is valid.

If passing a null pointer really makes sense then pass a nullObject instead.
quote:
Huh? How do you replace pointer arithmetic with references?

Pointer arithmetic? Do you mean for arrays? I use vectors and iterators or whatever container is appropriate. Say bye-bye to pointers!

[edited by - petewood on January 19, 2003 1:41:34 AM]

Share this post


Link to post
Share on other sites