passing by refrence in differnt ways and other pointer issues...

Started by
20 comments, last by Way Walker 19 years, 7 months ago
thanks for everyones response.

i know what a pointer is, and the meanings of pass by refrence and by value (didnt know about simulated pass by refrence though :S), i was just caught up in some of the syntax i was seeing in other persons source code (i realized the error also in not using -> operator in the simulated pass-by-refrence example) ...

i've never really learnt c then c++, i just started at c++ so i get really confused when i see c habit coding in a c++ progarm, (i coudnt figure out why people put typedef in front of structs for the longest time haha)

anyways, thanks for everyone clearning this all up for me.
Advertisement
can any one explain when references should be used, some people & tutorials go on about them as if they are really important and the "proper" way to do some things, even though pointers could be used instead, but at the same time I don't actually see references being used that much. Maybe the important thing to see, is when (because of the values etc in your code), it is essential to use referance instead of pointer. -Maybe first look at your code and say what is it I am working with at the moment, does it need referances or pointers?
BTW good answer XAI, maybe you should write a tutorial
Quote:Original post by Stevieboy
can any one explain when references should be used, some people & tutorials go on about them as if they are really important and the "proper" way to do some things, even though pointers could be used instead, but at the same time I don't actually see references being used that much. Maybe the important thing to see, is when (because of the values etc in your code), it is essential to use referance instead of pointer. -Maybe first look at your code and say what is it I am working with at the moment, does it need referances or pointers?


Basically, use a reference when you need a reference, and a pointer when you need a pointer. I think of references as an alias for an object, and pointers as an object containing the address of some other object. Thus, I use references when I want to refer to the same object under a different name (e.g. in the argument list of a function), and a pointer when I need to know where some object is (e.g. a tree structure). Or, in more concrete terms, I use a reference when I don't need to change which object I'm refering to, and a pointer when I may need to change which object I'm refering to.

Quote:
BTW good answer XAI, maybe you should write a tutorial


His answer was good at what's going on "underneath", but he doesn't go into how they're conceptually different. Just like, there's really no difference "underneath" between:

myObject.doSomething();

and:

MyClass__doSomething(&myObject);

but there's a rather large conceptual difference. (I think C++ doesn't allow double underscores in function names, and I'm pretty sure that's to allow the sort of name mangling I did above) In fact, the latter (aside from the double underscore, and assuming a similar solution) is how one would do it in C.
Quote:Original post by Way Walker
Quote:
BTW good answer XAI, maybe you should write a tutorial


His answer was good at what's going on "underneath"


i don't think it is, this statement:

Quote:Original post by Xai
a reference is just another syntax for using pointers, period


Is not always true, you can't make assumptions on how compilers implement/generates code for reference types, there not the same what you can assume because of the standard is one is an alias for some instance while the other is variable that holds addressess. You can also assume that a reference to some instance is the instance.

don't use pointers as parameters of a function just to simulate pass-by-reference actually use reference types for this the compiler could actually generate code that uses the instance passed with-out creating any copy what so ever including a copy of addressess that happens when using pointer types for parameters.

Quote:Original post by Stevieboy
can any one explain when references should be used


simple when you wont to pass a variable to a function by reference.

Quote:Original post by Stevieboy
some people & tutorials go on about them as if they are really important and the "proper" way to do some things, even though pointers could be used instead, but at the same time I don't actually see references being used that much.


references are used all the time (look in the c++ standard library headers for instance), with-out them you could not define a schematically correct copy constructor & assignement operators that everyone expects such as how the standard containers expect.
How else would you create a class that pretends it's an array *points to std::map*?
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Formats______________________________________________________________________________________
Quote:Original post by snk_kid
Quote:Original post by Way Walker
Quote:
BTW good answer XAI, maybe you should write a tutorial


His answer was good at what's going on "underneath"


i don't think it is, this statement:

Quote:Original post by Xai
a reference is just another syntax for using pointers, period


Is not always true, you can't make assumptions on how compilers implement/generates code for reference types


To be honest, I don't know how it's usually implemented, but I was under the impression (which could quite easily be wrong) that references in a function's argument list are usually implemented as pointers. In any case, it's not uncommon to make assumptions about how compilers implement various features. For instance, in C (I don't use C++ much, but I assume ( ;) ) that the same holds for it) one usually assumes that char strings are ASCII, wchar_t strings are Unicode, the bits of an int are in 2's complement with the bits in order, that float/double's follow IEEE 754, etc. However, none of these assumptions are guaranteed by the standard. I'd say the very fact that you can pass a null pointer as a reference on some implementations means you can make assumptions on how compilers implement/generate code for reference types. (and I think it would be more specific to say that this isn't allowed by the standard because *NULL is illegal, not because you can't test for NULL)

(Note, I'm very pedantic with my own code and try to only make assumptions guaranteed by the relevant standards, but some are more practically minded.)
Here is the convention for parameter passing that I use:

I never pass a non-const reference (i.e. &) parameter because it looks like a pass-by-value and it isn't. Looking at the following code, you would assume that the parameters x and y are not changed,
    foo( x, y ); 
when, in fact, they are.
    void foo( int & x, int & y )    {        ++x;        --y;    } 
Though not always feasible or practical, I avoid passing a const pointer because it appears that the referenced value might be changed when it won't. In this case,
    foo( &x, &y ); 
you have to look at the implementation of foo to see that the values of x and y are not changed.
    void foo( int const * x, int const * y )    {        ...    } 
In summary, declare parameters like this:
T xT const & xT * x 
and not like this:
T & xT const * x 

John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Quote:Original post by JohnBolton
Here is the convention for parameter passing that I use:

I never pass a non-const reference (i.e. &) parameter because it looks like a pass-by-value and it isn't. Looking at the following code, you would assume that the parameters x and y are not changed,
    foo( x, y ); 
when, in fact, they are.
    void foo( int & x, int & y )    {        ++x;        --y;    } 
Though not always feasible or practical, I avoid passing a const pointer because it appears that the referenced value might be changed when it won't. In this case,
    foo( &x, &y ); 
you have to look at the implementation of foo to see that the values of x and y are not changed.
    void foo( int const * x, int const * y )    {        ...    } 
In summary, declare parameters like this:
T xT const & xT * x 
and not like this:
T & xT const * x 


They is nothing wrong with non-constant reference types there used a in the standard library for agruments, the only problem is you can only use "lvalue" with them and if your compiler compiles with code that uses non-lvalues/literals for an argument of any kind i would say its time to update/upgrade or change your compiler.

Really thou if you need to mutate an instance of a user-defined type through a reference parameter in a free function or memeber function of some other type then maybe you should re-consider it as a method that mutates its self.
A point that was mentioned was that the compiler might be able to do some optimisations when references are used. Consider this example:

class A { int a; };class B { int b; };class C : public A, public B { int c; };C* pc = new C;B* pb = pc;


When casting the pointer 'pc', the compiler has to generate code for a NULL test before actually doing the cast (by adding the size of an int to the address).

When using references, the compiler can omit this NULL check.
Quote:Original post by nmi
A point that was mentioned was that the compiler might be able to do some optimisations when references are used. Consider this example:

class A { int a; };class B { int b; };class C : public A, public B { int c; };C* pc = new C;B* pb = pc;


When casting the pointer 'pc', the compiler has to generate code for a NULL test before actually doing the cast (by adding the size of an int to the address).

When using references, the compiler can omit this NULL check.


Really? Granted, I don't use C++ often so I don't think of things like this, but coming from C this is surprising. Assuming no exception handling, then new would return a null pointer on an error, but I would expect it to be the programmer's responsibility to check for the error. If there were exception handling, the only way you should get to the "B* pb = pc;" line is if new didn't return a null pointer.

Also, is it common for public inheritance to be done with pointers? I would've thought it would add sizeof(A) to the address, not sizeof(int) (or, I'm assuming, more correctly sizeof(A *)).

Quote:
They is nothing wrong with non-constant reference types there used a in the standard library for agruments, the only problem is you can only use "lvalue" with them and if your compiler compiles with code that uses non-lvalues/literals for an argument of any kind i would say its time to update/upgrade or change your compiler.


There's nothing wrong in the sense that non-const reference types as arguments are perfectly legal C++. There's nothing wrong in the sense that one can write readable code that uses non-const reference types as arguments. However, I believe it makes code slightly more readable to not use non-const reference types as arguments, so I don't. But, do what you feel is best (so long as it fits the coding practices of the project you're working on). For instance, I don't use the form:

if (SOME_CONSTANT == some_variable) { /*...*/ }

in my own code because I find it ugly and haven't yet been bitten by that particular bug.

Quote:
Really thou if you need to mutate an instance of a user-defined type through a reference parameter in a free function or memeber function of some other type then maybe you should re-consider it as a method that mutates its self.


Hmm? Could you elaborate? I'm not quite certain what you're saying. Are you saying we should require the user to encapsulate the modification in an instance method of their type? In general, I agree, or at least should require them to pass a function pointer. But that doesn't really solve the non-const reference issue. And I see nothing wrong with a free function (to a less extent member functions) mutating more than one of its pointer arguments (including the implicit this pointer).

This topic is closed to new replies.

Advertisement