Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / Vector Class

Author
Message
Greg_C
14
Years of Service
User Offline
Joined: 22nd May 2010
Location:
Posted: 19th Oct 2010 01:11
In this book I am reading they go over how to make a simple vector class and in the class they are changing the operators it looks like this:



Now I have always been confused as the reasoning behind using the reference operator (&) in the function parameters. Whats really the point of doing it that way rather than doing this Vector3 *a? Aren't they both asking for a memory address? I just have never used the reference operator in function parameters because I have never really come across a point to do it. I have seen this in a number of projects but I just don't really understand why? If anyone could shed some light on this I would greatly appreciate it.
dark coder
21
Years of Service
User Offline
Joined: 6th Oct 2002
Location: Japan
Posted: 19th Oct 2010 04:30
It allows you to have intuitive syntax, like:



Rather than:



Hawkblood
14
Years of Service
User Offline
Joined: 5th Dec 2009
Location:
Posted: 19th Oct 2010 04:49
The * operand means you want a memory location.
The & operand means you want the value at that location (for pointers).

If you are wanting to access a pointer's "place in memory it is pointing to", you would do something like this:

char a[100];
char *b;

We'll just say "a[]" is pointing at mem location 0x0a000 (or whatever). And you want to access that location using another variable. You could simply:
b=a;
but if you are passing the memory location thru a function like:
void funky(char &c){
dbText(0,0,c);
}
funky(a);
this will print out the contents of "a".

It's more useful when trying to pass a pointer to a class like:

The MG-> is an "indirection". Notice the MG declaration in the class above? It's a pointer. And I'm setting it's value to point to the memory location of GUIMenu by passing that value thru GUI_MENU_UTILITY &Menugui.
If I tried to pass GUIMenu directly it would simply make a reference to the pointer's location and not it's value (which is what I want).

Is your brain fuzzy yet? These make me fuzzy too. Mostly, I have to do some trial and error and then I remember what they can do and then it all makes sense again before I loose my sanity.....

The fastest code is the code never written.
Greg_C
14
Years of Service
User Offline
Joined: 22nd May 2010
Location:
Posted: 19th Oct 2010 08:39
Quote: "The * operand means you want a memory location.
The & operand means you want the value at that location (for pointers)."


Isn't the & the referencing operator. So in an example



that would print out the value inside of Var. Where as if I used the & operator it would print out the memory address. With all that said I did another test



Which this tells me that when I use that operator in function parameters it then acts as if it is actually taking the value that is inside the memory address. Could someone please explain that?
Abraxas77
14
Years of Service
User Offline
Joined: 26th Aug 2010
Location:
Posted: 19th Oct 2010 14:40 Edited at: 19th Oct 2010 14:54
I know it appears to behave differently, but if you look a little closer you'll see it acts the same. I can't remember from which book I read this, but there is a neat little mnemonic device that can help keep things clear. It goes like this:
 ● Read the reference operator, '&', as the "value at the address of ..."
 ● { int &i = var; } : "assign the integer value at the address of 'i' to the value of 'var'

 ● Read the dereference operator, '*', as "the address pointed to by ..."
 ● { int i = *pVar; } : "assign 'i' to the integer value at the address pointed to by 'pVar'





Your second example is what is called "passing by reference." Technically, this means when the function is called, the address of the parameter is pushed to the stack rather than the value itself. The implication is that changes to referenced parameters are reflected in the caller's environment. For example:



Here are some more examples of valid uses of pointers, the dereference operator, and the reference operator:


And now, seeing as how I've come to producing the answer to the question of live, the universe, and everything ... I think it is time to stop.


Hope that helps,
~Andrew~
Abraxas77
14
Years of Service
User Offline
Joined: 26th Aug 2010
Location:
Posted: 19th Oct 2010 14:59
Okay ... well, it's not really mnemonic at all .. but if you can manage to remember how to read the code ... how to both translate the symbols into words and the order in which to read them (understanding operator precedence as the compiler would) ... then things begin making a lot more sense.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 19th Oct 2010 15:29 Edited at: 19th Oct 2010 15:42
Abraxas77: you are using "assign" the other way around everywhere. This:



should be interpreted as:



Back to the original question. The official definition of a reference (from the C++ book by Stroustrup, the designer of the language) is that a reference is an alias, another name for a variable. Whatever happens to the reference, happens to the original variable. Technically it is a pointer but there are important differences:

- The value of a reference must be set at creation time and it cannot be changed later.
- A reference cannot be set to null.

The advantage is, as dark coder had already said, that it allows clearer and simpler syntax when you pass a parameter by reference to a function:

- Inside the function, you don't need to use the * operator to get the value of the variable (as you must do with pointers), you can simply use the name without any operator.
- You can use the . (dot) to access the members of a structure or class parameter instead of using the -> operator.

The & operator is used actually for two different purposes: 1. to take the "address of" a variable when you create a pointer, and 2. to declare a reference. Therefore:



EDIT: So the answer to the original question is, in short: reference parameters are good because inside the function you need to type less and the code is easier to read.
Hawkblood
14
Years of Service
User Offline
Joined: 5th Dec 2009
Location:
Posted: 19th Oct 2010 16:49
Quote: "So the answer to the original question is, in short: reference parameters are good because inside the function you need to type less and the code is easier to read. "

That's correct, but when used as a parameter to a function, it gives the function the ability to use the data at the location specified without having access to the variable in question.
If you had a variable:
int i;
.....
i=50;
ChangeValue(i);
dbText(0,0,dbStr(i));
......
inside a function and ChangeValue() was not a part of that class, the &i would give that function the address of what 'i' was pointed to :
void ChangeValue(int &v){
V=10;
}
So your output would be 10 instead of 50.
If you did not declare it that way, but like this:
void ChangeValue(int v){
v=10;
}
it would do nothing to 'i'.

The fastest code is the code never written.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 19th Oct 2010 17:17
Quote: "it gives the function the ability to use the data at the location specified"


True, but you can do the same with pointers. I was focusing on the difference between using pointers and using references and from that point of view, the only difference is convenience (less typing).

In the above post I mentioned two conveniences inside the called function but I forgot to mention the third: when passing a value to a function which has reference parameters, you don't need to use the "address of" operator in the function call, so it's less typing again.
Abraxas77
14
Years of Service
User Offline
Joined: 26th Aug 2010
Location:
Posted: 19th Oct 2010 17:26 Edited at: 19th Oct 2010 17:32
Also, when used as a return value of a function always you to use the function as an l-value.



Which, again, helps make code more intuitive and easier to read.

{edit: yeah, i know, not the best example because operator[] already returns a reference}
Hawkblood
14
Years of Service
User Offline
Joined: 5th Dec 2009
Location:
Posted: 19th Oct 2010 17:49
@Greg_C, is any of this helping? Or are we beating a dead horse?

The fastest code is the code never written.
Greg_C
14
Years of Service
User Offline
Joined: 22nd May 2010
Location:
Posted: 19th Oct 2010 20:51
Sorry for the late response guys and yes this has been very helpful. This was the kind of discussion I wanted to get out this question so I could get a better understanding of whats really going on. In the book I am reading they go over the reason behind using the & rather than just passing the value in.

Quote: "Passing an argument by value to a function involves a constructor call. Passing a const reference allows us to conceptually pass arguments by value, but actually they are passed by reference (address) and without any constructor calls for speed. In addition, if the function is not inline, passing a vector by value on the stack requires more space( and thus more time to push the argument on the stack) than passing by reference.
When we pass a vector variable to a function that accepts a const reference, the address of the argument is passed directly, just as if we had passed the arguments using a pointer. When we pass a vector expression to a function that excepts a const reference, the compiler generates code to evaluate the vector expression into a temporary variable, and then passes the address of the temporary to the function. So we get the best of both worlds. Conceptually, we get pass-by-value, so we can pass expressions to functions, letting the compiler do the tedious job of creating temporary variables. Under the hood, the function actually uses pass-by-reference, which is faster. "


This pretty much restates everything you guys were talking but I thought I would share this.

Login to post a reply

Server time is: 2024-09-28 16:26:32
Your offset time is: 2024-09-28 16:26:32