Does reference changes the state of the referent - c++

As I read
---references are not pointers it is the object itself,A reference is an entity that is an alias for another object.
---references can never represent NULL
---Reference variables allow two variable names to address the same memory location:
---it cannot later be made to refer to a different object
---A reference is not a variable as a variable is only introduced by the declaration of an object. An object is a region of storage and, in C++, references do not (necessarily) take up any storage.
now does the below line converts the variable integers to a constant integers
const Array& ref = integers
furthermore I read this
also which says that you can change the state of a referent.
Please suggest/clarify.

No, it does not convert integers. You now just have an alias for integers through which you can't change it. You can still change integers through the original name:
int i = 0;
int const& i_ref = i;
i = 5;
cout << i_ref; // outputs 5
The above examble also shows how you can change the state of the referee.

You cannot change the state of a const reference. Apart from that everything you mentioned in there is true.
So for example:
const int& ref = integers;
ref = 5;
will fail to compile. Where as
int& ref = integers;
ref = 5;
will compile and it will change the value stored in integers to 5.
Furthermore a const reference means that you cannot change value of the object it refers using the reference. You can still modify it using the original variable name. For example:
const int& ref = integers;
integers = 5;
std::cout<<ref<<", "<<integers<<std::endl;
is completely valid and will produce:
5, 5

Related

understanding references in c++

I have the following code:
int main() {
int x = 3;
int &ref = x;
int &ref2 = ref;
ref = 100;
std::cout <<ref;
std::cout <<ref2;
return 0;
}
This print out 100 and 100. I find it confusing. My understanding was that both ref and ref2 are references to the underlying object (x=3). We then change the value of ref.
As such, I expected 100 and 3.
You don't ever change the value of ref (the language does not let you rebind a reference). In fact, this is why you need to use reference initialisation when you create a reference: you can't write int &ref; ref = x; for example.
The statement ref = 100; changes the value of the object to which the reference is bound.
Hence the output of x, ref, and ref2 are identical.
My understanding was that both ref and ref2 are references to the underlying object (x=3)
Yes.
Well, they're both references to x, whose initial value is 3.
Essentially you have a single integer object, which you can refer to by the names any of the names x, ref or ref2.
We then change the value of ref
No, you're contradicting yourself.
Objects have values. References like ref are not objects, but references to objects, and they don't have a value of their own to change.
You said that ref is a reference, which is true - it is a reference to an object of type int, which can take a value, and whose value is changed when you write ref = 100. The names x, ref and ref2 still refer to the same integer object afterwards, but now its value is 100 instead of 3.
You cannot reseat a reference (make it refer to a different object), and a reference does not have a value to change. It refers to an object, whose value may be changed via the reference.
NB. I don't think this question is quite a duplicate of Can we reassign the reference, even though it contains some of the same misunderstanding.

How to use const_reference type to declare a variable and assign to it, the return value of front() function

I declared a vector and initialized it with three values as,
vector<int> vec{1, 2, 3};
I tried to assign the returned value of vec.front() to a reference variable, a.
How can I declare a using correct data type?
I tried,
vector<int>::const_reference &a = vec.front();
but what does this statement mean?
Can I first declare the variable a using proper data type and then use
a = vec.front();
to assign the returned value of vec.front() to the variable a? If yes, then what should I write?
Can I first declare the variable a using proper data type and then use
a = vec.front();
to assign the returned value of vec.front() to the variable a
a isn't a normal variable; it's a reference, and it's not legal to declare a reference without also stating what it refers to:
const int& a; // Illegal
Once a reference is declared, all operations performed on the variable are actually performed on the value it references, so you can't ever change what a reference references.
const int& a = b;
a = 10; // Changed the value of b.
I tried, vector<int>::const_reference &a = vec.front();
That seems an overly verbose way of saying:
const int& a = vec.front();
vec.front() returns a reference to the front element of the vector. const int& a = vec.front() declares variable a such that it is a reference to the front element of the vector.
That avoids copying by promising to read-only the value.
If you said:
int a = vec.front();
a would now be a copy of the first element of the array, but you are free to change it.
In the case of an int, there's no performance advantage. But if your vector was a vector of strings, taking a reference would avoid copying the string which could be a significant performance benefit over a reference if you don't intend to modify the contents.
std::string str = "hello world, this is a long string.";
const std::string& a = str; // Reference, no copy
std::string b = str; // Copy of str, takes extra effort
vector::front() returns a reference to the first element in a vector. So you can declare a reference of the type you store in the vector or you can use the types defined in the vector class (vector<int>::reference or vector<int>::const_reference) to declare the reference.
vector <int> v1;
v1.push_back(10);
v1.push_back(11);
vector<int>::reference var1 = v1.front( ); // Returns a reference to the first element you can modify or
int& x = v1.front(); // returns a reference to the first element you can modify
.....
vector<int>::const_reference var2 = v1.front(); // Returns a reference to the first element you can't modify
const int& y = v1.front(); // Return a reference to the first element you can't modify
Can I first declare the variable a using proper data type and then use
No. Since you are declaring a reference, it must be initialized during declaration.
One more thing:
vector<int>::const_reference &a=v1.front(); // This will not compile, because you are trying to take a reference of a reference
Besides the good answer by #kfsone, there is a (let me say) trick to do something similar to what you are asking.
I'd do everything, but what I'm showing you below.
Anyway, for the sake of completeness, if you have around a reference_wrapper, you can actually rebind it to a different reference from the one you used to create it.
That means that you can create a reference like object to use later, as you asked.
Here is a minimal, working example:
#include<functional>
#include<vector>
#include<cassert>
int main() {
int x;
std::reference_wrapper<int> w{x};
std::vector<int> vec{1, 2, 3};
w = vec[0];
w.get() = 42;
assert(vec[0] == 42);
}
Again, this is for the sake of curiosity.
I do not suggest you to do it in your code (unless you hate your colleagues, of course).

what is the difference between int &val2 = val and int val3 = val? [duplicate]

What would be a brief definition of a reference variable in C++?
A reference is an entity that is an alias for another object.
A reference is not a variable as a variable is only introduced by the declaration of an object. An object is a region of storage and, in C++, references do not (necessarily) take up any storage.
As objects and references are distinct groups of entities in C++ so the term "reference variable" isn't meaningful.
A reference variable provides an alias (alternative name) for a previously defined variable.
For example:
float total=100;
float &sum = total;
It means both total and sum are the same variables.
cout<< total;
cout << sum;
Both are going to give the same value, 100. Here the & operator is not the address operator; float & means a reference to float.
A reference variable is an alias (an alternate name) for an object. [From the C++ FAQ].
The first paragraph of the Wikipedia article could easily serve as a brief definition:
In the C++ programming language, a reference is a simple reference datatype that is less powerful but safer than the pointer type inherited from C.
And quoting from the same article:
C++ references differ from pointers in several essential ways:
It is not possible to refer directly to a reference object after it is defined; any occurrence of its name refers directly to the object it references.
Once a reference is created, it cannot be later made to reference another object; it cannot be reseated. This is often done with pointers.
References cannot be null, whereas pointers can; every reference refers to some object, although it may or may not be valid.
References cannot be uninitialized. Because it is impossible to reinitialize a reference, they must be initialized as soon as they are created. In particular, local and global variables must be initialized where they are defined, and references which are data members of class instances must be initialized in the initializer list of the class's constructor.
Further reading:
Wikipedia: Reference C++
Cprogramming.com: C++ References
Stack Overflow: Difference between pointer variable and reference variable in C++
It's a variable which references another one:
int foo;
int& bar = foo;
bar is now a reference, which is to say that bar holds the location of memory where foo lies.
See here for more information.
A Reference variable is an alias for the variable name.
It is different from the pointers in following ways:
You cannot have NULL references. You must always be able to assume that a reference is connected to a legitimate piece of storage.
Once a reference is initialized to an object, it cannot be changed to point to any another object whereas in case of pointer we can make it point to any other object at any time.
A reference must be initialized the time it is created. Pointers can be made initialized at any time.
Reference variables allow two variable names to address the same memory location:
int main()
{
int var1;
// var2 is a reference variable, holds same value as var1
int &var2 = var1;
var1 = 10;
std::cout << "var1 = " << var1 << std::endl;
std::cout << "var2 = " << var2 << std::endl;
}
Resource: LINK
A reference is an alternative label, an alias, for the object it is initialized with. Once a reference is initialized it can not be changed to be an alternative label or alias of some other object. After the initialization the reference or the object variable may be used interchangeably.
A reference has some of the characteristics of a const pointer to an object in that it is initialized when defined. And while what it references or points to can be changed, the reference or the const pointer itself can not be changed. However since a reference is an alternative label or alias it may or may not actually exist as a data object unlike a const pointer which will probably exist unless the compiler can optimize it away. And even if a reference is created as an actual entity by the compiler, that is compiler housekeeping and should be ignored since it officially does not exist much like the man behind the curtain in the Emerald City.
The following code samples gives examples comparing and contrasting reference with pointer and const pointer:
int myInt; // create a variable of type int, value not initialized
int myInt2 = 3; // create a second variable of type int with a value of 3
int &rInt = myInt; // create a reference to the variable of type int, myInt
rInt = 5; // myInt now has a value of 5, the reference is an alias for myInt
rInt++; // myInt now has a value of 6, the reference is an alias for myInt
rInt = myInt2; // myInt now has the same value as myInt2, a value of 3
int *pInt = &rInt; // pInt points to myInt
(*pInt)++; // increments myInt
pInt++; // increments the pointer which formerly pointed to myInt
int &rInt2; // error C2530: 'rInt2' : references must be initialized
int *pInt2; // just fine, uninitialized pointer is ok
int * const pInt3; // error C2734: 'pInt3' : const object must be initialized if not extern
int * const pInt4 = &myInt; // define and initialize const pointer
pInt4 = &myInt2; // error C3892: 'pInt4' : you cannot assign to a variable that is const
There are actually two kinds of references: an lvalue reference and an rvalue reference.
An lvalue reference is the same reference in the C++ language before C++11. An rvalue reference was introduced in C++11 to allow for a reference to a temporary object to assist with doing a move rather than a copy and some other actions where a copy is the wrong approach but a move is the right approach.
For example a comparison of lvalue reference and rvalue reference in the following simple source lines. Because these are int references that means that an assignment of a non-integer value results in the compiler doing a conversion which results in a temporary variable. An rvalue reference can bind to a temporary variable and an lvalue reference can not.
// assign a double to an int causing creation of temporary
int &rIntd1 = 1.2; // error C2440: 'initializing' : cannot convert from 'double' to 'int &'
int &&rIntd2 = 1.2; // warning C4244: 'initializing' : conversion from 'double' to 'int', possible loss of data
rInt = rIntd2; // myInt from the code above now has a value of 1, 1.2 was truncated when converting from double to int
A reference variable and a pointer variable are the exact same thing to the machine (the compiler will generate the same machine code).
The most obvious advantages of using a reference variable over a pointer variable in my knowledge:
Easy to understand (no address, de-reference all kinds of headache things)
Saves you a tiny bit of typing, adn thus probably less error-prone.
In the code below, the left side is using a reference variable, and the right side is using a pointer variable. They are the same thing to the machine, but you see the using reference variable saves you a little bit of typing.
Reference variable Pointer variable
int a = 1; ~~~~~~ int a = 1;
int &b = a; ~~~~~~ int *b = &a;
b = 2; ~~~~~~ *b = 2;
cout << a << '\n' ~~~~~~ cout << a << '\n'
==============================================
2 ~~~~~~ 2
Reference variables (let a), just say for easy understanding, another name of variable (let x), which holds the same exact memory location as that of x.
int &a = x; refers that a holds same memory location as that of x.
For example, say two roommates share the same room. One friends name is x and another friends name is a. If a changes the location of the table placed in the room, from position (x,y,z) to (x1,y1,z1) then changes are visible to friend x as well and vice versa.
A reference is an alternative name for an object. A reference variable provides an alias for previously defined variables. A reference declaration consists of a base type an & a reference variable equated to a variable name.
Page 79 ~ 80 C++ Primer 5th ed.
Object: A region of memory that has a type
Variable: Named object or reference
Reference: An alias for another object.

Initializing References and Variables In C++

Given the following c++ function:
int& ReturnAReference() {
/* Do something here */
}
Is there any difference between the two statements:
int normalVariable = ReturnAReference();
int& referenceVariable = ReturnAReferene();
Is one version preferred over the other?
Regarding this:
int normalVariable = ReturnAReference();
normalVariable is an integer, and is assigned the value of the int that ReturnAReference() references. As such incrementing, assigning, or doing anything else to normalVariable will not affect whatever ReturnAReference() has internally.
Regarding this:
int& referenceVariable = ReturnAReference();
referenceVariable is a reference to an integer that would otherwise be internal to ReturnAReference(). As such incrementing, assigning, or doing anything else to referenceVariable will affect whatever ReturnAReference() has internally.
What is preferred depends on what you're trying to accomplish, but in many cases the second approach (using referenceVariable) violates "encapsulation" ( http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming) ), which is considered poor design.
EDIT: And I should add that if ReturnAReference() is returning a reference to a variable that is local in that function, that reference will be invalid as soon as ReturnAReference() returns.
After a reference has been initialized, e.g. via
int i = 42;
int& r1 = i;
int& r2 = ReturnAReference();
int& r3(i);
int& r4{i}; // C++11
int& r5 = {i}; // C++11
it becomes an alias, i.e. another name, of the object it has been initialized with. It is not another integer. Note that in the language of the C++ Standard, an object is simply a region of storage, not necessarily an instance of a class.
As a reference is an alias, if you operate with the reference, you'll operate on the original object (the one it has been initialized with):
int i = 42;
int& r = i;
// r is now an alias for i, both refer to the same object
r = 21; // a true assignment
std::cout << i; // will print 21
The statement
int normalVariable = ReturnAReference();
introduces a new object of type int and a name for that object: normalVariable. This object is initialized with the object returned by ReturnAReference(), which means that the value of the returned object is copied into the new object called normalVariable.
On the other hand, the statement
int& referenceVariable = ReturnAReferene();
only introduces a new name for the object returned by ReturnAReference().
If your function would return a non-reference int, like int ReturnAnInt();, the statement
int& r = ReturnAnInt();
would become illegal, as the object returned by this function is a temporary, which only lives until the end of this line (in this case). In the next line, the name r would refer to an object that does not exist any more, so it has been made illegal to bind non-const references to temporary objects.
Let's suppose you have the following definitions :
int test = 4;
int& ReturnAReference() {
return test;
}
1) Is there any difference between the two statements:
int normalVariable = ReturnAReference();
In this case, normalVariable will hold a copy of the return value (not a reference), because the assignment operator copies the value referred by the return value into normalVariable. This means that after
normalVariable = 1;
normalVariable will now be 1, but test will still be 4.
However, if you were to have written
int& referenceVariable = ReturnAReferene();
and do
normalVariable = 1;
normalVariable would now be 1 and test would also be 1, since normalVariable is only an alias for test.
Be careful though when you return a reference. For instance, if you were to do
int& ReturnAReference() {
int i = 0;
return i;
}
the reference returned from ReturnAReference() would not be valid anymore, since it is only valid inside the function and will be destroyed when it is exited.
2) Is one version preferred over the other?
In the case of ints or other primitive types, I would prefer the int return value over int&, simply because an int is small and won't be expensive to copy (it will nearly always fit in a register). Also, the int& return value entails safety issues if the reference refers to a local variable. For classes or structs, it always depends, but you have to be careful when returning local variables by reference or by pointer.
If you want to modify the variable returned by reference from the function, or to keep track of any changes to its value, use int&. It's up to you to make sure the variable you are referencing will exist for as long as you access it. If you just care about the value of the variable returned by reference at that point, use int.
FYI, std::vector's operator [] and at functions return by reference allowing syntax such as the following v.at(0) = 2.

reference variable

In some text it is given that we can't assign constant values to a reference variable. When I executed such a program I could do it. Is there any condition we can't assign a constant value to a reference variable?
You can initialize a constant reference to a constant value.
const int &i = 12;
If the reference is not const, you get a compiler error.
int &i = 12; //compiler error
Constant values (e.g. literals) are (most of the time) stored in read-only segments of the memory. Consequently, you can't reference them using non-const references, because that would mean you could modify them.
You cannot assign a constant value to a non-constant reference, the same way you could not assign a constant value's address to a pointer pointing to a non-constant value.
At least, not without a const_cast.
Edit: If you were actually referring to literal values, Luc's answer is the better one. I was referring to const variables, not literals.
You may be a bit confused regarding the difference between "initialisation" and "assignment". These are different in C++ and understanding the difference is crucial to understanding the language. Ignoring references:
int x = 1; // initialisation
x = 1; // assignment
References can only be initialised
int & r = x; // initialisation
r = 2; // assigns 2 to x _not_ to r
There is no way of re-initialising a reference.
Regarding your question, as far as consts are concerned, you can initialise const reference with a const value:
const int & r2 = 42;