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.
Related
I was reading some code online and I found them passing node*& instead of just node* and I didn't really understand why.
My understanding was that you pass parameters by reference when you either want your changes to sort of propagate back to the original variable outside of the function (which a pointer would do) or if you wanted to avoid copying the object every time the function is called to avoid the copying overhead which is also what a pointer would do.
Am I wrong or are they? If I am, what am I getting wrong?
When you pass by reference, it acts as an alias -- be it a normal object or a pointer.
To explain in detail, let's consider below declaration:
int i = 10, *pi = &i;
Now following are the different meanings of passing and using them in various functions:
void foo_pointer (int* p) // 1st (can pass `&i` and `pi`)
{
*p = 0; // modifies `i`
p = nullptr; // no effect on `pi`
}
void foo_pointer_reference (int*& p) // 2nd (can pass `pi`)
{
*p = 0; // modifies `i`
p = nullptr; // modifies `pi`
}
void foo_const_pointer_reference (const int*& p) // 3rd (can pass `pi`)
{
*p = 0; // ERROR
p = nullptr; // modifies `pi`
}
void foo_const_pointer_const_reference (const int* const& p) // 4th (can pass `&i` and `pi`)
{
*p = 0; // ERROR
p = nullptr; // ERROR
}
From above examples, you can see that another use case of declaring T*& as a function parameter is that, it restricts only pointer passing to that function. i.e. in above case &i is not allowed to be passed to 2nd and 3rd functions. However pi can be passed to all the functions.
You can pass a pointer by reference if you want the function you call to change the pointer to point to something else.
Other than that, I don't see any valid reason (but that is sometimes a valid reason).
I am new to C++ programming, but I have experience in Java. I need guidance on how to pass objects to functions in C++.
Do I need to pass pointers, references, or non-pointer and non-reference values? I remember in Java there are no such issues since we pass just the variable that holds reference to the objects.
It would be great if you could also explain where to use each of those options.
Rules of thumb for C++11:
Pass by value, except when
you do not need ownership of the object and a simple alias will do, in which case you pass by const reference,
you must mutate the object, in which case, use pass by a non-const lvalue reference,
you pass objects of derived classes as base classes, in which case you need to pass by reference. (Use the previous rules to determine whether to pass by const reference or not.)
Passing by pointer is virtually never advised. Optional parameters are best expressed as a std::optional (boost::optional for older std libs), and aliasing is done fine by reference.
C++11's move semantics make passing and returning by value much more attractive even for complex objects.
Rules of thumb for C++03:
Pass arguments by const reference, except when
they are to be changed inside the function and such changes should be reflected outside, in which case you pass by non-const reference
the function should be callable without any argument, in which case you pass by pointer, so that users can pass NULL/0/nullptr instead; apply the previous rule to determine whether you should pass by a pointer to a const argument
they are of built-in types, which can be passed by copy
they are to be changed inside the function and such changes should not be reflected outside, in which case you can pass by copy (an alternative would be to pass according to the previous rules and make a copy inside of the function)
(here, "pass by value" is called "pass by copy", because passing by value always creates a copy in C++03)
There's more to this, but these few beginner's rules will get you quite far.
There are some differences in calling conventions in C++ and Java. In C++ there are technically speaking only two conventions: pass-by-value and pass-by-reference, with some literature including a third pass-by-pointer convention (that is actually pass-by-value of a pointer type). On top of that, you can add const-ness to the type of the argument, enhancing the semantics.
Pass by reference
Passing by reference means that the function will conceptually receive your object instance and not a copy of it. The reference is conceptually an alias to the object that was used in the calling context, and cannot be null. All operations performed inside the function apply to the object outside the function. This convention is not available in Java or C.
Pass by value (and pass-by-pointer)
The compiler will generate a copy of the object in the calling context and use that copy inside the function. All operations performed inside the function are done to the copy, not the external element. This is the convention for primitive types in Java.
An special version of it is passing a pointer (address-of the object) into a function. The function receives the pointer, and any and all operations applied to the pointer itself are applied to the copy (pointer), on the other hand, operations applied to the dereferenced pointer will apply to the object instance at that memory location, so the function can have side effects. The effect of using pass-by-value of a pointer to the object will allow the internal function to modify external values, as with pass-by-reference and will also allow for optional values (pass a null pointer).
This is the convention used in C when a function needs to modify an external variable, and the convention used in Java with reference types: the reference is copied, but the referred object is the same: changes to the reference/pointer are not visible outside the function, but changes to the pointed memory are.
Adding const to the equation
In C++ you can assign constant-ness to objects when defining variables, pointers and references at different levels. You can declare a variable to be constant, you can declare a reference to a constant instance, and you can define all pointers to constant objects, constant pointers to mutable objects and constant pointers to constant elements. Conversely in Java you can only define one level of constant-ness (final keyword): that of the variable (instance for primitive types, reference for reference types), but you cannot define a reference to an immutable element (unless the class itself is immutable).
This is extensively used in C++ calling conventions. When the objects are small you can pass the object by value. The compiler will generate a copy, but that copy is not an expensive operation. For any other type, if the function will not change the object, you can pass a reference to a constant instance (usually called constant reference) of the type. This will not copy the object, but pass it into the function. But at the same time the compiler will guarantee that the object is not changed inside the function.
Rules of thumb
This are some basic rules to follow:
Prefer pass-by-value for primitive types
Prefer pass-by-reference with references to constant for other types
If the function needs to modify the argument use pass-by-reference
If the argument is optional, use pass-by-pointer (to constant if the optional value should not be modified)
There are other small deviations from these rules, the first of which is handling ownership of an object. When an object is dynamically allocated with new, it must be deallocated with delete (or the [] versions thereof). The object or function that is responsible for the destruction of the object is considered the owner of the resource. When a dynamically allocated object is created in a piece of code, but the ownership is transfered to a different element it is usually done with pass-by-pointer semantics, or if possible with smart pointers.
Side note
It is important to insist in the importance of the difference between C++ and Java references. In C++ references are conceptually the instance of the object, not an accessor to it. The simplest example is implementing a swap function:
// C++
class Type; // defined somewhere before, with the appropriate operations
void swap( Type & a, Type & b ) {
Type tmp = a;
a = b;
b = tmp;
}
int main() {
Type a, b;
Type old_a = a, old_b = b;
swap( a, b );
assert( a == old_b );
assert( b == old_a );
}
The swap function above changes both its arguments through the use of references. The closest code in Java:
public class C {
// ...
public static void swap( C a, C b ) {
C tmp = a;
a = b;
b = tmp;
}
public static void main( String args[] ) {
C a = new C();
C b = new C();
C old_a = a;
C old_b = b;
swap( a, b );
// a and b remain unchanged a==old_a, and b==old_b
}
}
The Java version of the code will modify the copies of the references internally, but will not modify the actual objects externally. Java references are C pointers without pointer arithmetic that get passed by value into functions.
There are several cases to consider.
Parameter modified ("out" and "in/out" parameters)
void modifies(T ¶m);
// vs
void modifies(T *param);
This case is mostly about style: do you want the code to look like call(obj) or call(&obj)? However, there are two points where the difference matters: the optional case, below, and you want to use a reference when overloading operators.
...and optional
void modifies(T *param=0); // default value optional, too
// vs
void modifies();
void modifies(T ¶m);
Parameter not modified
void uses(T const ¶m);
// vs
void uses(T param);
This is the interesting case. The rule of thumb is "cheap to copy" types are passed by value — these are generally small types (but not always) — while others are passed by const ref. However, if you need to make a copy within your function regardless, you should pass by value. (Yes, this exposes a bit of implementation detail. C'est le C++.)
...and optional
void uses(T const *param=0); // default value optional, too
// vs
void uses();
void uses(T const ¶m); // or optional(T param)
There's the least difference here between all situations, so choose whichever makes your life easiest.
Const by value is an implementation detail
void f(T);
void f(T const);
These declarations are actually the exact same function! When passing by value, const is purely an implementation detail. Try it out:
void f(int);
void f(int const) { /* implements above function, not an overload */ }
typedef void NC(int); // typedefing function types
typedef void C(int const);
NC *nc = &f; // nc is a function pointer
C *c = nc; // C and NC are identical types
Pass by value:
void func (vector v)
Pass variables by value when the function needs complete isolation from the environment i.e. to prevent the function from modifying the original variable as well as to prevent other threads from modifying its value while the function is being executed.
The downside is the CPU cycles and extra memory spent to copy the object.
Pass by const reference:
void func (const vector& v);
This form emulates pass-by-value behavior while removing the copying overhead. The function gets read access to the original object, but cannot modify its value.
The downside is thread safety: any change made to the original object by another thread will show up inside the function while it's still executing.
Pass by non-const reference:
void func (vector& v)
Use this when the function has to write back some value to the variable, which will ultimately get used by the caller.
Just like the const reference case, this is not thread-safe.
Pass by const pointer:
void func (const vector* vp);
Functionally same as pass by const-reference except for the different syntax, plus the fact that the calling function can pass NULL pointer to indicate it has no valid data to pass.
Not thread-safe.
Pass by non-const pointer:
void func (vector* vp);
Similar to non-const reference. The caller typically sets the variable to NULL when the function is not supposed to write back a value. This convention is seen in many glibc APIs. Example:
void func (string* str, /* ... */) {
if (str != NULL) {
*str = some_value; // assign to *str only if it's non-null
}
}
Just like all pass by reference/pointer, not thread-safe.
Since no one mentioned I am adding on it, When you pass a object to a function in c++ the default copy constructor of the object is called if you dont have one which creates a clone of the object and then pass it to the method, so when you change the object values that will reflect on the copy of the object instead of the original object, that is the problem in c++, So if you make all the class attributes to be pointers, then the copy constructors will copy the addresses of the pointer attributes , so when the method invocations on the object which manipulates the values stored in pointer attributes addresses, the changes also reflect in the original object which is passed as a parameter, so this can behave same a Java but dont forget that all your class attributes must be pointers, also you should change the values of pointers, will be much clear with code explanation.
Class CPlusPlusJavaFunctionality {
public:
CPlusPlusJavaFunctionality(){
attribute = new int;
*attribute = value;
}
void setValue(int value){
*attribute = value;
}
void getValue(){
return *attribute;
}
~ CPlusPlusJavaFuncitonality(){
delete(attribute);
}
private:
int *attribute;
}
void changeObjectAttribute(CPlusPlusJavaFunctionality obj, int value){
int* prt = obj.attribute;
*ptr = value;
}
int main(){
CPlusPlusJavaFunctionality obj;
obj.setValue(10);
cout<< obj.getValue(); //output: 10
changeObjectAttribute(obj, 15);
cout<< obj.getValue(); //output: 15
}
But this is not good idea as you will be ending up writing lot of code involving with pointers, which are prone for memory leaks and do not forget to call destructors. And to avoid this c++ have copy constructors where you will create new memory when the objects containing pointers are passed to function arguments which will stop manipulating other objects data, Java does pass by value and value is reference, so it do not require copy constructors.
Do I need to pass pointers, references, or non-pointer and non-reference values?
This is a question that matters when writing a function and choosing the types of the parameters it takes. That choice will affect how the function is called and it depends on a few things.
The simplest option is to pass objects by value. This basically creates a copy of the object in the function, which has many advantages. But sometimes copying is costly, in which case a constant reference, const&, is usually best. And sometimes you need your object to be changed by the function. Then a non-constant reference, &, is needed.
For guidance on the choice of parameter types, see the Functions section of the C++ Core Guidelines, starting with F.15. As a general rule, try to avoid raw pointers, *.
There are three methods of passing an object to a function as a parameter:
Pass by reference
pass by value
adding constant in parameter
Go through the following example:
class Sample
{
public:
int *ptr;
int mVar;
Sample(int i)
{
mVar = 4;
ptr = new int(i);
}
~Sample()
{
delete ptr;
}
void PrintVal()
{
cout << "The value of the pointer is " << *ptr << endl
<< "The value of the variable is " << mVar;
}
};
void SomeFunc(Sample x)
{
cout << "Say i am in someFunc " << endl;
}
int main()
{
Sample s1= 10;
SomeFunc(s1);
s1.PrintVal();
char ch;
cin >> ch;
}
Output:
Say i am in someFunc
The value of the pointer is -17891602
The value of the variable is 4
The following are the ways to pass a arguments/parameters to function in C++.
1. by value.
// passing parameters by value . . .
void foo(int x)
{
x = 6;
}
2. by reference.
// passing parameters by reference . . .
void foo(const int &x) // x is a const reference
{
x = 6;
}
// passing parameters by const reference . . .
void foo(const int &x) // x is a const reference
{
x = 6; // compile error: a const reference cannot have its value changed!
}
3. by object.
class abc
{
display()
{
cout<<"Class abc";
}
}
// pass object by value
void show(abc S)
{
cout<<S.display();
}
// pass object by reference
void show(abc& S)
{
cout<<S.display();
}
int y=5;
int *yPtr = nullptr;
yPtr = &y;
I understand that the pointer stores the address of y. and calling *yPtr dereferences y.
If I have a call to the void function:
int main()
{
int number = 5;
function( &number );
}
void function( int *nPtr)
{
*nPtr = *nPtr * *nPtr;
}
if the function takes a pointer as argument, how can the call to the function use an address?
I understand that nPtr stores addresses but why couldn't it be defined as.
void functions (int &ref)
{
ref = ref * ref;
}
My main question would be: Why does a function receiving an address argument need a pointer parameter to receive the address?
By using a pass-by-reference parameter, you force your function not the copy the value of the parameter itself, instead, to use the actual variable you provide. So, for a more clear view, see below:
void function( int number )
{
cout << number;
}
function( myInt ); // function will copy myInt, into its local variables stack
but, by using the pass-by-reference method, like this:
void function ( int & number )
{
cout << number
}
function( myInt ); // function will not copy myInt into its local variables stack, instead, it will use the already existent myInt variable.
There is no difference in how to compiler will work with pass-by-pointer and pass-by-reference parameters. Instead, the call of your function will look like so:
void function_p( int *number )
{
cout << *number;
}
void function_r( int & number )
{
cout << number;
}
// and the calls
function_p( &myInt ); // it is required to use address-of operator here
function_r( myInt ); // the effect will be the same, but with less effort in writing that address-of operator
In C++11, programmers started to use pass-by-reference method, in general, ordinarily because it has an easier writing "template".
To complete the answer to your question, the * and & operators refer only to the type of the parameter, so that they create compound types. A compound type is a type that is defined in terms of another type. C++ has several compound types, two of which are references and pointers.
You can understand that they only affect the type of a variable (in our case, a parameter), by writing them in a proper way:
int* p1; // we will read this: pointer p1 points to an int
int* p2 = &var1; // we read this: pointer p2 points to int variable var1
int var1 = 12;
int& ref1 = var1; // and we read this: ref1 is a reference to var1
You can generally consider references represent a different for the same block of memory.
you did mean
void functions (int &ref)
{
ref = ref * ref;
}
that's how you use refs, avoiding all the '*'s of pointers syntax
This is another of those quirky things of C++. Passing by reference is not the same as passing a pointer. When you do something like
void functions (int &ref)
You can pass an actual variables into functions (rather than pointers to them) like
int a = 12;
functions(a);
And inside the function you have no need to dereference. Notice that you are passing by reference, rather than passing a reference.
When you pass a reference, or pointer to something, you use star as such
void function( int *nPtr)
And thus you have to dereference with a *
Note also that you get the reference to a variable (or constant) by putting & in front of it, but you declare a reference or pointer by putting a * in front of it. At the same time, you dereference a pointer also by putting a * in front of it.
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 (¶m == 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...
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.