Sign in to follow this  

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

This topic is 4859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

ok i'm really not sure on why some people do certain things and have no idea the reason behind them ... for instance ... assuming this class ...
class myClass
{
        int x;
    public:        
        void show (int X)
        {
            x = X;
        }
        void set ()
        {
            cout << x << endl;
        }
        int get ()
        {
            return x;
        }
};


now usually i see passing by refrence like this ... void someFunc (myClass &c) { c.set (100); } ... then in main myClass b; someFunc (b); b.show (); now i see passing by refrence like this ... void someFunc (myClass *c) { c.set (100); } ... main again myClass b; someFunc (&b); b.show (); ... ok so is there any difference here? then sometimes i see pointers used for no real reason ... int sum (myClass a, myClass b) { myClass value; myClass *p = &value; p -> set (a.get () + b.get ()); return value; } ... what is the point of using a pointer? do people sometimes only use pointers so they can use the -> operator (assuming it's not overloaded) ... often i cant see why people use pointers when they can just directly access which ever variable they are working on with . operator ... sometimes the use of pointers confuses me ... am i missing something in all of this? thanks for any help.

Share this post


Link to post
Share on other sites
references are automaticaly dereferenced pointers when you say
int & x=y you must know that the address of x is the address of y
-x=3 means that y=3("x is y")
-you could do it also like this int* x=&y;*x=3(by dereferencing x)
-keep in mind that references never "talk about themselves" they always are somebody else

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Ohh yes, that explanation was clear as mud. google it's friend, read books, this subject IS WAY TOO BIG to try to explain in few words here.

Share this post


Link to post
Share on other sites
Quote:
Original post by ekrax
ok i'm really not sure on why some people do certain things and have no idea the reason behind them ... for instance ...

assuming this class ...

*** Source Snippet Removed ***

now usually i see passing by refrence like this ...

void someFunc (myClass &c)
{
c.set (100);
}

... then in main
myClass b;
someFunc (b);
b.show ();

now i see passing by refrence like this ...

void someFunc (myClass *c)
{
c.set (100);
}

... main again
myClass b;
someFunc (&b);
b.show ();

... ok so is there any difference here?


very subtle difference, pointers are variables too so it's still pass-by-value but your making copies of address and not the instance it refers to this is called simulated pass-by-reference, don't use pointers for pass-by-references actually use reference types for this it's safe to assume that the instance passed into a function with a reference type as a parameter is the actual instance used. Also you can have a reference to a pointer if you need to actually read/modify the original pointer.

another thing pointers could point to one instance or the first element of an array, or some other dynamic data structure.

Quote:
Original post by ekrax
then sometimes i see pointers used for no real reason ...
int sum (myClass a, myClass b)
{
myClass value;
myClass *p = &value;
p -> set (a.get () + b.get ());
return value;
}

... what is the point of using a pointer?


Thats is completely pointless & looks nothing more than syntactic sugar for somebody.

Quote:
Original post by ekrax
do people sometimes only use pointers so they can use the -> operator (assuming it's not overloaded) ... often i cant see why people use pointers when they can just directly access which ever variable they are working on with . operator ...

sometimes the use of pointers confuses me ... am i missing something in all of this?

thanks for any help.


Yes there are people who just loving using ->.

But there are times where you have to use pointers and there is no way around it, for instance dynamic polymorphism (but you can use references aswell for this), to build dynamic data structures, static polymorphism (STL iterators act like pointers so you can actually use raw pointers aswell), to implement simple callback mechanisms.

EDIT: You may aswell take out dynamic polymorphism for "have to use" as you can use reference types aswell.

Share this post


Link to post
Share on other sites
Four more reasons someone might use pointers to simulate pass-by-reference in C++:

1) Some feel that using non-const references makes code look like pass-by-value even if its not. Using pointers instead of references when the function modifies the variable's value is a little bit of self-documentation and a little reminder to the reader of the code that it may not come back the same.

2) Can pass a null-pointer which may have some meaning (e.g. use an internal (i.e. static) buffer)

3) Compatibility with C libraries (e.g. need to use arrays instead of vectors)

4) They're a C programmer forced to use C++ and do so out of habit.

Share this post


Link to post
Share on other sites
Quote:
Original post by Way Walker
4) They're a C programmer forced to use C++ and do so out of habit.


5) They're a Java programmer forced to use C++ and can't stand having both pointers and references in the same language. ;) (Java uses '.'s, but their *meaning* is more like '->'. "Java has no pointers", they say, or at least used to say; but that's marketing-speak which is ignorant of the Java object model.)

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
5) They're a Java programmer forced to use C++ and can't stand having both pointers and references in the same language. ;) (Java uses '.'s, but their *meaning* is more like '->'. "Java has no pointers", they say, or at least used to say; but that's marketing-speak which is ignorant of the Java object model.)


Hmm... does anyone know which meaning of "reference" came first? I know Smalltalk's variables behave in much the same way as Java's references, and Smalltalkers use the term "reference" these days, but I'm not sure if they stole that from Java or not. Or some other language? I don't know much about language history :)

In any case, it would've saved me much confusion when I first looked at Java had they said "We don't allow pointer arithmetic" rather than "We don't have pointers" (that, and not having both float and Float).

Share this post


Link to post
Share on other sites
When passing by reference, the parameter passed is for all intensive purposes the original passed variable. When passing a pointer to a something, you are passing the address of the object, not the actual object itself. On the surface, they would appear to be the same, but they are not. In one instance, you are passing a reference to the object, in the other you are passing the address of the object.

They both provide access to the original object passed, but are used in different ways.

One such example of a difference is a bug in your sample code.
When operating on a pointer to the object, you would have to use the -> operator instead of the . operator. When you pass a reference, you are working on the actual original object, so there is no need for the -> operator.

It should be:

void someFunc (myClass &c)
{
c.set (100);
}

void someFunc (myClass *c)
{
c->set (100);
}

Share this post


Link to post
Share on other sites
Pointers can be very powerful and dangerous tools. References allow for some of the benefits of pointers without the danger. However references cannot be used in all cases. For instance dynamic memory, or if you want to change the data it points to.

Event though references are pointers "underneath" they are syntactically different, and limited in what they can do.

Use references whenever it makes sense, only use pointers when they are needed.

Share this post


Link to post
Share on other sites
pointers are references ... period.

In C, passing a non-pointer was called "pass by value" and passing a pointer was called "pass by reference", because in the 50s, 60s, and 70s, when computer science was invented, these two categories of manipulation were discovered to be the only two core concepts needed to describe everything that can be done by the computer ... a value in memory is either the actual value you want to use in an operation, or in some way a "referece" to the value you want to use.

Pointers are memory addresses, and therefore are the most natual form of reference for any computer operation to use ... I mean, your could have written the chip to take letters like 'cs' to refer to the address of the code segment, but the performance cost of making the computer do conversion from human ideas, to the numbers it really understands just doesn't make much sense.

In C++, a reference is just another syntax for using pointers, period. Just like in C++ struct and class are nearly identical and can be emulate each other, so too can everything with references be done with pointers. The only thing that cannot be done with a reference is assigning it to 0 and then checking it for the value 0 (null). A referece can BE null, through accident of programming or mistake, but it is not SUPPOSED to ever be set to an invalid pointer, mainly because it cannot be tested to see if it is null. So when you write something that needs to be able to be null, you MUST use pointers, when you want to pass something which wants the efficiency of pointers, but pass by value semantics, then you should probably use a const reference. For anything in between, the choice is yours.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.)

Share this post


Link to post
Share on other sites
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 x
T const & x
T * x
and not like this:
T & x
T const * x

Share this post


Link to post
Share on other sites
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 x
T const & x
T * x
and not like this:
T & x
T 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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
Quote:
Original post by Way Walker
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.


Actually the topic of this thread is "passing by refrence in differnt ways and other pointer issues...". The little example was used to show the difference between passing a pointer to an object and passing a reference to that object. In both cases, the value pushed onto the stack would be the same (the address of the object), but the different semantic of passing by reference lets the compiler do some optimisations.

If you take the example above and consider this code:

void bar(B* y)
{ ... }
void foo(C* x)
{
bar(x);
}
int main()
{
C* c = new C;
foo(c);
}


This would be the case when using pointers. When you use references, just replace the '*' in 'foo' and 'bar' by '&' and in main replace 'c' by '&c'.

You may check the generated code with a disassembler and depending on your compiler (and settings) you might see a difference.

At least my compiler (gcc3.4.1) generated code to check for a NULL pointer and when not NULL the cast was done. When using references, there was no such check. (when foo calls bar)

When you say it is the programmers task to check for NULL-pointers, you are right. But actually, aren't references just there for that point ? You don't have to check for an error because you are not able (besides tricking the compiler with NULL-references) to call a function with a reference to nowhere.

Quote:

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


Acutally the size of the object A in the example above is exactly the size of an int, and thats what I said. In the general case the compiler would add sizeof(A) to the pointer when doing the cast. (NOT sizeof(A*) which is just the size of a pointer)

And yes, sometimes it is necessary to use public inheritance with pointers. (consider a class that is the specialisation of another class and in addition extends a ListItem to be used as a member in a List) Anyways, it doesn't matter if the inheritance is public or not. The compiler has to arrange the data of the class in memory. If you have multiple base classes (e.g. an interface with abstract virtual functions and another class with some data) there is no way around...

Share this post


Link to post
Share on other sites
Quote:
Original post by nmi
Actually the topic of this thread is "passing by refrence in differnt ways and other pointer issues...". The little example was used to show the difference between passing a pointer to an object and passing a reference to that object. In both cases, the value pushed onto the stack would be the same (the address of the object), but the different semantic of passing by reference lets the compiler do some optimisations.

If you take the example above and consider this code:

void bar(B* y)
{ ... }
void foo(C* x)
{
bar(x);
}
int main()
{
C* c = new C;
foo(c);
}


This would be the case when using pointers. When you use references, just replace the '*' in 'foo' and 'bar' by '&' and in main replace 'c' by '&c'.


I think you mean "in main replace 'c' by '*c'".

Quote:

You may check the generated code with a disassembler and depending on your compiler (and settings) you might see a difference.

At least my compiler (gcc3.4.1) generated code to check for a NULL pointer and when not NULL the cast was done. When using references, there was no such check. (when foo calls bar)


Ah, I see. It would have to maintain the NULL pointer. I missed that because, in the example you gave, it would be safe to assume that it was not NULL (well... maybe... would it be possible for new to be overloaded and the compiler not know at that point?).

Quote:

When you say it is the programmers task to check for NULL-pointers, you are right. But actually, aren't references just there for that point ? You don't have to check for an error because you are not able (besides tricking the compiler with NULL-references) to call a function with a reference to nowhere.


What it came down to was I don't use C++ enough to think of things like the compiler having to maintain the NULL when casting between related (through inheritance) types.

Quote:

Quote:

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


Acutally the size of the object A in the example above is exactly the size of an int, and thats what I said. In the general case the compiler would add sizeof(A) to the pointer when doing the cast. (NOT sizeof(A*) which is just the size of a pointer)


Well, I doubt it's required to be the size of an int, and I don't know the C++ standard well enough to judge whether it'd be useful to stray from that or not in the general case. Really, though, I didn't read the actual contents of the class because that was irrelevant to the example and my pedantic side took over. My appologies.

Quote:

And yes, sometimes it is necessary to use public inheritance with pointers.


You misunderstood what I was saying. I was trying to rationalize the sizeof(int), and guessed that some compilers may choose to implement public inheritance as:

class C {
A *__A;
B *__B;
/* class C stuff */
};

instead of

class C {
A __A;
B __B;
};

In which case, when casting to B, you would add sizeof(A *) instead of sizeof(A).

Share this post


Link to post
Share on other sites

This topic is 4859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this