Initialising a C++ Reference - why not using the adress-of operator? - c++

Why does the initialisation of C++ references works without the "adress-of" operator (which is &)?
Isn't the assignment of Object with a type A to a reference with a type A& wrong?
Shouldn't the assignment use the "&" operator on the right side?
int var = 2
int& ref = var //why can we assign var of type 'int' to ref of type 'int&'?
int& ref = &var //shouldn't it be like that, so that we will assign the ADRESS to the reference?
EDIT:
To summarize it:
References are alternative names for Objects.
The type of References is created by appending '&' to the type of the referenced object.
References are the same as the references object in every context.
They do not store the memory of the object as pointers do, the presence of the 'adress-of' operator '&' was misleading here.

A reference does not hold the address of the object, as you imply by your comments. That is a pointer. references != pointers.
A reference is an alias to an object which is why that type of assignment works.

int& is a type
&var is an operation to take address.
Same symbol. Totally different menings. Probably designed specifically to keep C++ inaccessible to newcomers.

"I know, that compilers implement referencies as pointers"
No, they don't. This is a common source of confusion. When you do this:
int p;
int *r = &p;
You are creating, say, a 32-bit pointer into memory that you can use to manipulate data.
However, when you do this:
int p;
int& r = p;
You aren't using a pointer to p. There is an object p, that may reside in a register, or the stack or the heap, it's not important. The declaration means that r is also referencing that same object. It is not a pointer to the object: if make a pointer, you're making a new object. You are saying "r points to p." However, using a reference, you are saying "r is p." No new object is created (a pointer). For all intents and purposes, int& r is p, because any use of it references (not points to) p.
Let me put it this way:
It's like saying there's this person, Dave.
He lives at (made up address)
This points to Dave.
And then he has a nickname, OrgnlDave.
OrgnlDave doesn't point to Dave, it is Dave, it is just another way of saying it. There is only one Dave. Saying "hi OrgnlDave" is equal to saying "hi Dave," which is different from sending Dave a letter.
In pseudocode,
person Dave;
address(Dave, made-up-address) pointer;
person& OrgnlDave means Dave; // and we indicate that by using the &
Hi(pointer); // Sends Dave a cordial letter
Hi(Dave); // Says hi to Dave
Hi(OrgnlDave); // Says hi to Dave

Related

Beginner Question: C++ Pointer/Addresses - & after variable not before?

I'm a rusty amateur C++ programmer coming back after along time and moving on from OpenGL 2.0 to Vulkan.
I'm trying to understand the code behind the tutorials I'm reading not just copy, but don't understand the & part of the following:
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
Why is the & after exception? My understanding is the pointer is usually after the variable and the address before it, such as:
int* pintVar;
pintVar = &intVar;
Has this got something to do with binding a constant reference 'exception' to a temporary object 'e'?
As you can see I'm trying to research/google it but not totally understanding it or why.
Any help would be appreciated.
& has different meanings depending on context. In a declaration, it means reference to. e.g.
int a = 42;
int &b = a; // b is a reference to a
// b is essentially an alias of a (they both have the same address, for example)
// i.e. changes to b will be reflected in a, and vice versa
Here's some reference that explains this in more depth.
When & is used on an already existing variable, this means address-of. e.g.
int a = 42;
int *b = &a; // b points to a (i.e. b holds the address of a).
So in your example, e is a const reference to whatever exception is passed in (since the parameter of a function declares a variable).
Analogous question:
int* pintVar;
"Why is the * after int? What is the indirection operator doing there? Why isn't it before the variable name such as in here?"
int intVar = *pintVar;
Well, you see * symbol has multiple meanings. Perhaps you already understand this: Within a compound type name, it signifies a pointer type. Within an expression it signifies an operator. It can be either the unary indirection operator (*pintVar) or the binary multiplication operator (a * b).
In the exactly same way, & symbol has multiple meanings. Within a compound type name, it signifies a reference type. Within an expression it signifies an operator. It can be either the unary addressof operator (&intVar) or the binary bitwise AND operator (a & b).
So, const T& is a reference to const T, just like const T* would be a pointer to const T.
Both reference and pointer are forms of indirection, and are quite smilar. Their differences are:
Pointers are objects, references are not objects
Because references are not objects, there is no way to take the address of a reference, and there is no such thing as a pointer to reference or a reference to reference.
There are also no arrays of references.
A (non-const) pointer can be assigned to point to another object. A reference is bound to a single object for its entire lifetime.
Pointer can be null, a reference cannot be.
You must indirect through a pointer explicitly using an indirection operator. All operations on a reference implicitly indirect through the reference, and apply to the referred object instead.
Assignment of reference is assignment of the referred object.
Taking the address of a reference variable is taking address of the referred object.
Pointers are iterators for arrays; You can do pointer arithmetic to iterate the elements. Adding one to a pointer results in pointer to the successive array element. There is no reference arithmetic. Because of the implicit indirection, adding one to reference adds one to the referred object.
Has this got something to do with binding a constant reference 'exception' to a temporary object 'e'?
There are many right words there, but I don't understand what you are trying to mean by them.
e is a variable. The type of the variable is const std::exception& i.e. reference to constant exception. Upon throw, the reference is bound to the exception object that was thrown.

How to obtain pointer to reference member?

Consider this code:
struct AA
{
int& rr;
};
Is there a way to obtain pointer (or maybe reference) to AA::rr in order to obtain this?
AA* aa;
auto mm = &AA::rr; // error: cannot create pointer to reference member ‘AA::rr’
aa ->* mm;
Also in gcc-7.0.1 decltype(AA::mm) is just int&. Is this according to the standard? And does this make sense?
EDIT
Sorry guys, I formulated the question not quite well. No complaints to the fact that references are not objects or that there is no such thing as pointer to a reference. The goal is quite selfish. Given struct AA { int& rr; }; I just want to have a function like this:
template < typename Class, typename Member >
void test(Member Class::*) { }
that when calling test(&AA::rr) I want Class to be AA and Member to be int& or int. So I don't even need the pointer itself but its type that will allow to retrieve the class type and the member type.
How to obtain pointer to reference (member)?
You cannot obtain a pointers to (or references to, or arrays of) references. There is no such type as "pointer to reference" in C++. This is because references are not required to have storage, so there might not even be an address where the reference is stored.
When you apply addressof operator on a reference, what you get is the address of the object that is referred to.
Picture speaks a thousand words
References doesn't really have a container in the memory, they serves more like an alias to the original variable, thus you cannot get pointer to reference because references doesn't have their own memory location.
However, you can get the address of reference, which is the variable it is referencing. In this example, if you cout &rx and &x, they are the same.
So probably you would want to get a pointer to the object it is referencing, rather than pointer to reference

C++ Primer Plus this pointer example

Sorry for turning to here for such a basic question, but can someone just quickly clear this up for me? I'll then delete the thread so as not to cause noob clutter.
In the following example from the C++ Primer Plus text, doesn't the & operator in the function declaration designate that the function returns a pointer to a Stock object? Why then does the function proceed to return the s and this objects by value instead?
"...What you want to return, however, is not this, because this is the address of the object. You want to return the object itself, and that is symbolized by *this. (Recall that applying the dereferencing operator * to a pointer yields the value to which the pointer points.) Now you can complete the method definition by using *this as an alias for the invoking object."
const Stock & Stock::topval(const Stock & s) const {
if (s.total_val > total_val)
return s; // argument object
else
return *this; // invoking object
}
Yeah, that's confusing. C++ massively overloads every symbol, because there just aren't enough symbols on the keyboard.
The ampersand & is used for two different meanings which are conceptually similar, but are actually completely different language features.
Meaning 1: Reference type declaration. Append an ampersand to type A which means a-reference-to-type-A. Example:
Stock x;
Stock& s = x; // now s is a reference to x
Meaning 2: Address-of operator. A unary operator that returns a pointer to its argument. Example:
Stock x;
Stock* s = &x; // now s a pointer to x
Reminder: References and pointers are exactly the same thing, except they have different syntax, and references can never be null, and you can't have a reference to a reference.
Don't delete this thread, we love n00bs. I'm a n00b myself.
const Stock & means return a const reference to an object. A pointer to an object would be const Stock *. Don't mix the two! So the this pointer is being dereferenced and returned.

Why do parameters passed by reference in C++ not require a dereference operator?

I'm new to the C++ community, and just have a quick question about how C++ passes variables by reference to functions.
When you want to pass a variable by reference in C++, you add an & to whatever argument you want to pass by reference. How come when you assign a value to a variable that is being passed by reference why do you say variable = value; instead of saying *variable = value?
void add_five_to_variable(int &value) {
// If passing by reference uses pointers,
// then why wouldn't you say *value += 5?
// Or does C++ do some behind the scene stuff here?
value += 5;
}
int main() {
int i = 1;
add_five_to_variable(i);
cout << i << endl; // i = 6
return 0;
}
If C++ is using pointers to do this with behind the scenes magic, why aren't dereferences needed like with pointers? Any insight would be much appreciated.
When you write,
int *p = ...;
*p = 3;
That is syntax for assigning 3 to the object referred to by the pointer p. When you write,
int &r = ...;
r = 3;
That is syntax for assigning 3 to the object referred to by the reference r. The syntax and the implementation are different. References are implemented using pointers (except when they're optimized out), but the syntax is different.
So you could say that the dereferencing happens automatically, when needed.
C++ uses pointers behind the scenes but hides all that complication from you. Passing by reference also enables you to avoid all the problems asssoicated with invalid pointers.
When you pass an object to a function by reference, you manipulate the object directly in the function, without referring to its address like with pointers. Thus, when manipulating this variable, you don't want to dereference it with the *variable syntax. This is good practice to pass objects by reference because:
A reference can't be redefined to point to another object
It can't be null. you have to pass a valid object of that type to the function
How the compiler achieves the "pass by reference" is not really relevant in your case.
The article in Wikipedia is a good ressource.
There are two questions in one, it seems:
one question is about syntax: the difference between pointer and reference
the other is about mechanics and implementation: the in-memory representation of a reference
Let's address the two separately.
Syntax of references and pointers
A pointer is, conceptually, a "sign" (as road sign) toward an object. It allows 2 kind of actions:
actions on the pointee (or object pointed to)
actions on the pointer itself
The operator* and operator-> allow you to access the pointee, to differenciate it from your accesses to the pointer itself.
A reference is not a "sign", it's an alias. For the duration of its life, come hell or high water, it will point to the same object, nothing you can do about it. Therefore, since you cannot access the reference itself, there is no point it bothering you with weird syntax * or ->. Ironically, not using weird syntax is called syntactic sugar.
Mechanics of a reference
The C++ Standard is silent on the implementation of references, it merely hints that if the compiler can it is allowed to remove them. For example, in the following case:
int main() {
int a = 0;
int& b = a;
b = 1;
return b;
}
A good compiler will realize that b is just a proxy for a, no room for doubts, and thus simply directly access a and optimize b out.
As you guessed, a likely representation of a reference is (under the hood) a pointer, but do not let it bother you, it does not affect the syntax or semantics. It does mean however that a number of woes of pointers (like access to objects that have been deleted for example) also affect references.
The explicit dereference is not required by design - that's for convenience. When you use . on a reference the compiler emits code necessary to access the real object - this will often include dereferencing a pointer, but that's done without requiring an explicit dereference in your code.

Use of the & operator in C++ function signatures

I'm currently reading through Accelerated C++ and I realized I don't really understand how & works in function signatures.
int* ptr=&num;
means that ptr now holds the address to num, but what does that mean?
void DoSomething(string& str)
from what I understand that is a pass by reference of a variable (which means passing the address) but when I do
void DoSomething(string& str)
{
string copy=str;
}
what it creates is a copy of str. What I thought it would do is raise an error since I'm trying to assign a pointer to a variable.
What is happening here? And what is the meaning of using * and & in function calls?
A reference is not a pointer, they're different although they serve similar purpose.
You can think of a reference as an alias to another variable, i.e. the second variable having the same address. It doesn't contain address itself, it just references the same portion of memory as the variable it's initialized from.
So
string s = "Hello, wordl";
string* p = &s; // Here you get an address of s
string& r = s; // Here, r is a reference to s
s = "Hello, world"; // corrected
assert( s == *p ); // this should be familiar to you, dereferencing a pointer
assert( s == r ); // this will always be true, they are twins, or the same thing rather
string copy1 = *p; // this is to make a copy using a pointer
string copy = r; // this is what you saw, hope now you understand it better.
The & character in C++ is dual purpose. It can mean (at least)
Take the address of a value
Declare a reference to a type
The use you're referring to in the function signature is an instance of #2. The parameter string& str is a reference to a string instance. This is not just limited to function signatures, it can occur in method bodies as well.
void Example() {
string s1 = "example";
string& s2 = s1; // s2 is now a reference to s1
}
I would recommend checking out the C++ FAQ entry on references as it's a good introduction to them.
https://isocpp.org/wiki/faq/references
You shouldn't know anything about pointers until you get to chapter 10 of Accelerated C++ !
A reference creates another name, an alias, for something that exists elsewhere. That's it. There are no hidden pointers or addresses involved. Don't look behind the curtain!
Think of a guy named Robert
guy Robert;
Sometimes you may want to call him Bob
guy& Bob = Robert;
Now Bob and Robert both refer to the same guy. You don't get his address (or phone number), just another name for the same thing.
In your function
void DoSomething(string& str)
{
  string copy=str;
}
it works exactly the same, str is another name for some string that exists somewhere else.
Don't bother with how that happens, just think of a reference as a name for some object.
The compiler has to figure out how to connect the names, you don't have to.
In the case of assigning variables (ie, int* ptr = &value), using the ampersand will return the address of your variable (in this case, address of value).
In function parameters, using the ampersand means you're passing access, or reference, to the same physical area in memory of the variable (if you don't use it, a copy is sent instead). If you use an asterisk as part of the parameter, you're specifying that you're passing a variable pointer, which will achieve almost the same thing. The difference here is that with an ampersand you'll have direct access to the variable via the name, but if you pass a pointer, you'll have to deference that pointer to get and manipulate the actual value:
void increase1(int &value) {
value++;
}
void increase2(int *value) {
(*value)++;
}
void increase3(int value) {
value++;
}
Note that increase3 does nothing to the original value you pass it because only a copy is sent:
int main() {
int number = 5;
increase1(number);
increase2(&number);
increase3(number);
return 0;
}
The value of number at the end of the 3 function calls is 7, not 8.
It's a reference which allows the function to modify the passed string, unlike a normal string parameter where modification would not affect the string passed to the function.
You will often see a parameter of type const string& which is done for performance purposes as a reference internally doesn't create a copy of the string.
int* ptr=&num;
1st case: Since ptr is a memory and it stores the address of a variable. The & operator returns the address of num in memory.
void DoSomething(string& str)
2nd case: The ampersand operator is used to show that the variable is being passed by reference and can be changed by the function.
So Basically the & operator has 2 functions depending on the context.
While pass by reference may be implemented by the compiler by passing the address as a pointer, semantically it has nothing to do with addresses or pointers. in simple terms it is merely an alias for a variable.
C++ has a lot of cases where syntax is reused in different contexts with different semantics and this is one of those cases.
In the case of:
int* ptr=&num;
you are declaring a variable named ptr with a type of an int * (int pointer), and setting its value to the "address of the variable num" (&num). The "addressof" operator (&) returns a pointer.
In the case of:
void DoSomething(string& str)
you are declaring the first parameter of the DoSomething() method to be of type "reference to string". Effectively, this is the C++ way of defining "pass-by-reference".
Note that while the & operator operates similarly in these cases, it's not acting in the same way. Specifically, when used as an operator, you're telling the compiler to take the address of the variable specified; when used in a method signature, you're telling the compiler that the argument is a reference. And note as well, that the "argument as a reference" bit is different from having an argument that is a pointer; the reference argument (&) gets dereferenced automatically, and there's never any exposure to the method as to where the underlying data is stored; with a pointer argument, you're still passing by reference, but you're exposing to the method where the variable is stored, and potentially exposing problems if the method fails to do a dereference (which happens more often than you might think).
You're inexplicitly copy-constructing copy from str. Yes, str is a reference, but that doesn't mean you can't construct another object from it. In c++, the & operator means one of 3 things -
When you're defining a normal reference variable, you create an alias for an object.
When you use it in a function paramater, it is passed by reference - you are also making an alias of an object, as apposed to a copy. You don't notice any difference in this case, because it basically is the object you passed to it. It does make a difference when the objects you pass contain pointers etc.
The last (and mostly irrelevent to your case) meaning of & is the bitwise AND.
Another way to think about a reference (albeit slightly incorrect) is syntactic sugar for a dereferenced pointer.