C++ Modes for Passing Arguments
- By Value
- A copy of variable will be created
- Any modification of the variable inside the function have no effect on original variable
- By Reference
- A reference to the original variable is created (i.e. alias)
- Any modification of the variable inside the function happens also on original variable
- By Pointer
- A pointer to the original variable is passed
- Any modification to the pointed object inside the function happens also on the original variable
- Access to the pointed variable must happen using pointer syntax
Example
- By Value
int foo(int x) // pass x by value, it is copied
{
return ++x; // x is modified
}
int main()
{
int y = 5;
cout << y << endl; // 5
cout << foo(y) << endl; // 6
cout << y << endl; // 5
return 0;
}
If x was a large object instead of being an int, then passing it by value would be expensive. Better to pass it by const reference.
- By Reference
int foo(int &x) // pass x by reference
{
return ++x; // x is modified
}
int main()
{
int y = 5;
cout << y << endl; // 5
cout << foo(y) << endl; // 6
cout << y << endl; // 6
return 0;
}
- By Pointer
int foo(int *x) // pass x by pointer
{
return ++ *x; // x is modified
}
int main()
{
int y = 5;
cout << y << endl; // 5
cout << foo(y) << endl; // 6
cout << y << endl; // 6
return 0;
}
For Struct
- If passed by value, the struct is copied into the argument, which might be costly for large structures
- Generally we pass struct arguments by:
- reference, if we intend to modify them inside the function
- const reference otherwise
struct ComplexNumber
{
double r, i;
};
// we pass the complex numbers by const reference, so we avoid the cost of copying them
// we specify them as const, to make it clear that they will not be modified in the function
ComplexNumber mult(const ComplexNumber& a, const ComplexNumber& b)
{
ComplexNumber c;
c.r = a.r * b.r - a.i * b.i;
c.i = a.r * b.i + a.i * b.r;
return c;
}
int main()
{
ComplexNumber x = {1, 2}, y = {2, -3}, z = mult(x, y);
std::cout << z.r << "+" << z.i << "i\n";
}