References as function arguments? - c++

I have a trouble with references.
Consider this code:
void pseudo_increase(int a){a++;}
int main(){
int a = 0;
//..
pseudo_increase(a);
//..
}
Here, the value of variable a will not increase as a clone or copy of it is passed and not variable itself.
Now let us consider an another example:
void true_increase(int& a){a++;}
int main(){
int a = 0;
//..
true_increase(a);
//..
}
Here it is said value of a will increase - but why?
When true_increase(a) is called, a copy of a will be passed. It will be a different variable. Hence &a will be different from true address of a. So how is the value of a increased?
Correct me where I am wrong.

Consider the following example:
int a = 1;
int &b = a;
b = 2; // this will set a to 2
printf("a = %d\n", a); //output: a = 2
Here b can be treated like an alias for a. Whatever you assign to b, will be assigned to a as well (because b is a reference to a). Passing a parameter by reference is no different:
void foo(int &b)
{
b = 2;
}
int main()
{
int a = 1;
foo(a);
printf("a = %d\n", a); //output: a = 2
return 0;
}

When true_increase(a) is called , copy of 'a' will be passed
That's where you're wrong. A reference to a will be made. That's what the & is for next to the parameter type. Any operation that happens to a reference is applied to the referent.

in your true_increase(int & a) function, what the code inside is getting is NOT A COPY of the integer value that you have specified. it is a reference to the very same memory location in which your integer value is residing in computer memory. Therefore, any changes done through that reference will happen to the actual integer you originally declared, not to a copy of it. Hence, when the function returns, any change that you did to the variable via the reference will be reflected in the original variable itself. This is the concept of passing values by reference in C++.
In the first case, as you have mentioned, a copy of the original variable is used and therefore whatever you did inside the function is not reflected in the original variable.

Related

Reason Behind Passing By reference to a Function in C++?

Here I'm Coding in C++.
int main()
{
int setAcapacity = 10;
int setANOE = 0;
int *setA;
createSet(&setA, setAcapacity);
}
void createSet(int **set, int n)
{
*set = new int[n];
}
can someone please explain it reason behind passing by reference to createSet Functions..Thanks in advance!!
At first, you do not pass by reference, you pass by pointer!
By reference would look like this:
int createSet(int*& set, int n)
// ^ reference to pointer
{
set = new int[n]; // assign to referenced value
}
createSet(setA, setAcapacity);
// ^ no need to take address
There are two reasons you would want to pass by reference or pointer:
The object to be passed is large, copying would be inefficient. In these cases, you typically pass a const reference or pointer to const.
The object passed shall be modified within the function. This is the case in your example, where a new value is assigned to the pointer setA outside the function which is passed via the pointer to named set.
What you do in int createSet(int **set, int n) you pass a pointer to a pointer; not a reference to a pointer. To pass a reference: int createSet(int * & set, int n).
In case of pass-by-reference, your code would looks like:
void createSet(int * & set, int n) // '&' for reference
{
set = new int[n];
}
int main()
{
int setAcapacity = 10;
int setANOE = 0;
int *setA = nullptr; // Better to initialize
createSet(setA, setAcapacity);
}
For your question: The difference between pass-by-pointer/reference and pass-by-value is that modifications made to arguments passed in by pointer/reference in the called function have effect in the calling function, whereas modifications made to arguments passed in by value in the called function can not affect the calling function. The #value# in your case is: #int-pointer#.
You pass a pointer/reference to the #value# because you want the assignment to target setA of the calling function: main(). That's why you also pass, in your original code, the address of setA. So new can store the new pointer in that address.
In addition, in many cases: Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.

how to properly pass a pointer with the address of a variable from a function into another function that takes in a reference [duplicate]

Is the following code (func1()) correct if it has to return i? I remember reading somewhere that there is a problem when returning a reference to a local variable. How is it different from func2()?
int& func1()
{
int i;
i = 1;
return i;
}
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
This code snippet:
int& func1()
{
int i;
i = 1;
return i;
}
will not work because you're returning an alias (a reference) to an object with a lifetime limited to the scope of the function call. That means once func1() returns, int i dies, making the reference returned from the function worthless because it now refers to an object that doesn't exist.
int main()
{
int& p = func1();
/* p is garbage */
}
The second version does work because the variable is allocated on the free store, which is not bound to the lifetime of the function call. However, you are responsible for deleteing the allocated int.
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int* p = func2();
/* pointee still exists */
delete p; // get rid of it
}
Typically you would wrap the pointer in some RAII class and/or a factory function so you don't have to delete it yourself.
In either case, you can just return the value itself (although I realize the example you provided was probably contrived):
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
Note that it's perfectly fine to return big objects the same way func3() returns primitive values because just about every compiler nowadays implements some form of return value optimization:
class big_object
{
public:
big_object(/* constructor arguments */);
~big_object();
big_object(const big_object& rhs);
big_object& operator=(const big_object& rhs);
/* public methods */
private:
/* data members */
};
big_object func4()
{
return big_object(/* constructor arguments */);
}
int main()
{
// no copy is actually made, if your compiler supports RVO
big_object o = func4();
}
Interestingly, binding a temporary to a const reference is perfectly legal C++.
int main()
{
// This works! The returned temporary will last as long as the reference exists
const big_object& o = func4();
// This does *not* work! It's not legal C++ because reference is not const.
// big_object& o = func4();
}
A local variable is memory on the stack, and that memory is not automatically invalidated when you go out of scope. From a function deeper nested (higher on the stack in memory), it’s perfectly safe to access this memory.
Once the function returns and ends though, things get dangerous.
Usually the memory is not deleted or overwritten when you return, meaning the memory at that address is still containing your data - the pointer seems valid.
Until another function builds up the stack and overwrites it.
This is why this can work for a while - and then suddenly cease to function after one particularly deeply nested set of functions, or a function with really huge sized or many local objects, reaches that stack-memory again.
It even can happen that you reach the same program part again, and overwrite your old local function variable with the new function variable. All this is very dangerous and should be heavily discouraged.
Do not use pointers to local objects!
A good thing to remember are these simple rules, and they apply to both parameters and return types...
Value - makes a copy of the item in question.
Pointer - refers to the address of the item in question.
Reference - is literally the item in question.
There is a time and place for each, so make sure you get to know them. Local variables, as you've shown here, are just that, limited to the time they are locally alive in the function scope. In your example having a return type of int* and returning &i would have been equally incorrect. You would be better off in that case doing this...
void func1(int& oValue)
{
oValue = 1;
}
Doing so would directly change the value of your passed in parameter. Whereas this code...
void func1(int oValue)
{
oValue = 1;
}
would not. It would just change the value of oValue local to the function call. The reason for this is because you'd actually be changing just a "local" copy of oValue, and not oValue itself.

Using Variable When Declaring Constructors [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
This is confusing me:
class CDummy
{
public:
int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param)
{
if (&param == this)
{
return true; //ampersand sign on left side??
}
else
{
return false;
}
}
int main ()
{
CDummy a;
CDummy* b = &a;
if ( b->isitme(a) )
{
cout << "yes, &a is b";
}
return 0;
}
In C & usually means the address of a var. What does it mean here? Is this a fancy way of pointer notation?
The reason I am assuming it is a pointer notation because this is a pointer after all and we are checking for equality of two pointers.
I am studying from cplusplus.com and they have this example.
The & has more the one meanings:
1) take the address of a variable
int x;
void* p = &x;
//p will now point to x, as &x is the address of x
2) pass an argument by reference to a function
void foo(CDummy& x);
//you pass x by reference
//if you modify x inside the function, the change will be applied to the original variable
//a copy is not created for x, the original one is used
//this is preffered for passing large objects
//to prevent changes, pass by const reference:
void fooconst(const CDummy& x);
3) declare a reference variable
int k = 0;
int& r = k;
//r is a reference to k
r = 3;
assert( k == 3 );
4) bitwise and operator
int a = 3 & 1; // a = 1
n) others???
To start, note that
this
is a special pointer ( == memory address) to the class its in.
First, an object is instantiated:
CDummy a;
Next, a pointer is instantiated:
CDummy *b;
Next, the memory address of a is assigned to the pointer b:
b = &a;
Next, the method CDummy::isitme(CDummy &param) is called:
b->isitme(a);
A test is evaluated inside this method:
if (&param == this) // do something
Here's the tricky part. param is an object of type CDummy, but &param is the memory address of param. So the memory address of param is tested against another memory address called "this". If you copy the memory address of the object this method is called from into the argument of this method, this will result in true.
This kind of evaluation is usually done when overloading the copy constructor
MyClass& MyClass::operator=(const MyClass &other) {
// if a programmer tries to copy the same object into itself, protect
// from this behavior via this route
if (&other == this) return *this;
else {
// otherwise truly copy other into this
}
}
Also note the usage of *this, where this is being dereferenced. That is, instead of returning the memory address, return the object located at that memory address.
Well the CDummy& param that is declared as a parameter of the function CDummy::isitme is actually a reference which is "like" a pointer, but different. The important thing to note about references is that inside functions where they are passed as parameters, you really have a reference to the instance of the type, not "just" a pointer to it. So, on the line with the comment, the '&' is functioning just like in C, it is getting the address of the argument passed in, and comparing it to this which is, of course, a pointer to the instance of the class the method is being called on.

Will returning by const lvalue reference extend lifetime of variable? [duplicate]

Is the following code (func1()) correct if it has to return i? I remember reading somewhere that there is a problem when returning a reference to a local variable. How is it different from func2()?
int& func1()
{
int i;
i = 1;
return i;
}
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
This code snippet:
int& func1()
{
int i;
i = 1;
return i;
}
will not work because you're returning an alias (a reference) to an object with a lifetime limited to the scope of the function call. That means once func1() returns, int i dies, making the reference returned from the function worthless because it now refers to an object that doesn't exist.
int main()
{
int& p = func1();
/* p is garbage */
}
The second version does work because the variable is allocated on the free store, which is not bound to the lifetime of the function call. However, you are responsible for deleteing the allocated int.
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int* p = func2();
/* pointee still exists */
delete p; // get rid of it
}
Typically you would wrap the pointer in some RAII class and/or a factory function so you don't have to delete it yourself.
In either case, you can just return the value itself (although I realize the example you provided was probably contrived):
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
Note that it's perfectly fine to return big objects the same way func3() returns primitive values because just about every compiler nowadays implements some form of return value optimization:
class big_object
{
public:
big_object(/* constructor arguments */);
~big_object();
big_object(const big_object& rhs);
big_object& operator=(const big_object& rhs);
/* public methods */
private:
/* data members */
};
big_object func4()
{
return big_object(/* constructor arguments */);
}
int main()
{
// no copy is actually made, if your compiler supports RVO
big_object o = func4();
}
Interestingly, binding a temporary to a const reference is perfectly legal C++.
int main()
{
// This works! The returned temporary will last as long as the reference exists
const big_object& o = func4();
// This does *not* work! It's not legal C++ because reference is not const.
// big_object& o = func4();
}
A local variable is memory on the stack, and that memory is not automatically invalidated when you go out of scope. From a function deeper nested (higher on the stack in memory), it’s perfectly safe to access this memory.
Once the function returns and ends though, things get dangerous.
Usually the memory is not deleted or overwritten when you return, meaning the memory at that address is still containing your data - the pointer seems valid.
Until another function builds up the stack and overwrites it.
This is why this can work for a while - and then suddenly cease to function after one particularly deeply nested set of functions, or a function with really huge sized or many local objects, reaches that stack-memory again.
It even can happen that you reach the same program part again, and overwrite your old local function variable with the new function variable. All this is very dangerous and should be heavily discouraged.
Do not use pointers to local objects!
A good thing to remember are these simple rules, and they apply to both parameters and return types...
Value - makes a copy of the item in question.
Pointer - refers to the address of the item in question.
Reference - is literally the item in question.
There is a time and place for each, so make sure you get to know them. Local variables, as you've shown here, are just that, limited to the time they are locally alive in the function scope. In your example having a return type of int* and returning &i would have been equally incorrect. You would be better off in that case doing this...
void func1(int& oValue)
{
oValue = 1;
}
Doing so would directly change the value of your passed in parameter. Whereas this code...
void func1(int oValue)
{
oValue = 1;
}
would not. It would just change the value of oValue local to the function call. The reason for this is because you'd actually be changing just a "local" copy of oValue, and not oValue itself.

passing object by reference in C++

The usual way to pass a variable by reference in C++(also C) is as follows:
void _someFunction(dataType *name){ // dataType e.g int,char,float etc.
/****
definition
*/
}
int main(){
dataType v;
_somefunction(&v); //address of variable v being passed
return 0;
}
But to my surprise, I noticed when passing an object by reference the name of object itself serves the purpose(no & symbol required) and that during declaration/definition of function no * symbol is required before the argument.
The following example should make it clear:
// this
#include <iostream>
using namespace std;
class CDummy {
public:
int isitme (CDummy& param); //why not (CDummy* param);
};
int CDummy::isitme (CDummy& param)
{
if (&param == this) return true;
else return false;
}
int main () {
CDummy a;
CDummy* b = &a;
if ( b->isitme(a) ) //why not isitme(&a)
cout << "yes, &a is b";
return 0;
}
I have problem understanding why is this special treatment done with class . Even structures which are almost like a class are not used this way. Is object name treated as address as in case of arrays?
What seems to be confusing you is the fact that functions that are declared to be pass-by-reference (using the &) aren't called using actual addresses, i.e. &a.
The simple answer is that declaring a function as pass-by-reference:
void foo(int& x);
is all we need. It's then passed by reference automatically.
You now call this function like so:
int y = 5;
foo(y);
and y will be passed by reference.
You could also do it like this (but why would you? The mantra is: Use references when possible, pointers when needed) :
#include <iostream>
using namespace std;
class CDummy {
public:
int isitme (CDummy* param);
};
int CDummy::isitme (CDummy* param)
{
if (param == this) return true;
else return false;
}
int main () {
CDummy a;
CDummy* b = &a; // assigning address of a to b
if ( b->isitme(&a) ) // Called with &a (address of a) instead of a
cout << "yes, &a is b";
return 0;
}
Output:
yes, &a is b
A reference is really a pointer with enough sugar to make it taste nice... ;)
But it also uses a different syntax to pointers, which makes it a bit easier to use references than pointers. Because of this, we don't need & when calling the function that takes the pointer - the compiler deals with that for you. And you don't need * to get the content of a reference.
To call a reference an alias is a pretty accurate description - it is "another name for the same thing". So when a is passed as a reference, we're really passing a, not a copy of a - it is done (internally) by passing the address of a, but you don't need to worry about how that works [unless you are writing your own compiler, but then there are lots of other fun things you need to know when writing your own compiler, that you don't need to worry about when you are just programming].
Note that references work the same way for int or a class type.
Ok, well it seems that you are confusing pass-by-reference with pass-by-value. Also, C and C++ are different languages. C doesn't support pass-by-reference.
Here are two C++ examples of pass by value:
// ex.1
int add(int a, int b)
{
return a + b;
}
// ex.2
void add(int a, int b, int *result)
{
*result = a + b;
}
void main()
{
int result = 0;
// ex.1
result = add(2,2); // result will be 4 after call
// ex.2
add(2,3,&result); // result will be 5 after call
}
When ex.1 is called, the constants 2 and 2 are passed into the function by making local copies of them on the stack. When the function returns, the stack is popped off and anything passed to the function on the stack is effectively gone.
The same thing happens in ex.2, except this time, a pointer to an int variable is also passed on the stack. The function uses this pointer (which is simply a memory address) to dereference and change the value at that memory address in order to "return" the result. Since the function needs a memory address as a parameter, then we must supply it with one, which we do by using the & "address-of" operator on the variable result.
Here are two C++ examples of pass-by-reference:
// ex.3
int add(int &a, int &b)
{
return a+b;
}
// ex.4
void add(int &a, int &b, int &result)
{
result = a + b;
}
void main()
{
int result = 0;
// ex.3
result = add(2,2); // result = 2 after call
// ex.4
add(2,3,result); // result = 5 after call
}
Both of these functions have the same end result as the first two examples, but the difference is in how they are called, and how the compiler handles them.
First, lets clear up how pass-by-reference works. In pass-by-reference, generally the compiler implementation will use a "pointer" variable in the final executable in order to access the referenced variable, (or so seems to be the consensus) but this doesn't have to be true. Technically, the compiler can simply substitute the referenced variable's memory address directly, and I suspect this to be more true than generally believed. So, when using a reference, it could actually produce a more efficient executable, even if only slightly.
Next, obviously the way a function is called when using pass-by-reference is no different than pass-by-value, and the effect is that you have direct access to the original variables within the function. This has the result of encapsulation by hiding the implementation details from the caller. The downside is that you cannot change the passed in parameters without also changing the original variables outside of the function. In functions where you want the performance improvement from not having to copy large objects, but you don't want to modify the original object, then prefix the reference parameters with const.
Lastly, you cannot change a reference after it has been made, unlike a pointer variable, and they must be initialized upon creation.
Hope I covered everything, and that it was all understandable.
Passing by reference in the above case is just an alias for the actual object.
You'll be referring to the actual object just with a different name.
There are many advantages which references offer compared to pointer references.
One thing that I have to add is that there is no reference in C.
Secondly, this is the language syntax convention.
& - is an address operator but it also mean a reference - all depends on usa case
If there was some "reference" keyword instead of & you could write
int CDummy::isitme (reference CDummy param)
but this is C++ and we should accept it advantages and disadvantages...