Passing Parameters By References
## Passing Parameters by Reference in C++
In C++, when we pass arguments to a function, they are passed by value by default. This means a copy of the argument is made in memory, and any modifications made to the parameter inside the function do not affect the original variable.
However, C++ provides a powerful feature called **References**. Passing parameters by reference allows a function to access and modify the original caller's variables directly without making a copy. This is both memory-efficient and functionally powerful.
---
### Why Use Pass-by-Reference?
1. **Modify the Caller's Arguments:** It allows a function to change the values of the variables passed to it.
2. **Performance Optimization:** Copying large objects (like custom classes, structs, or large vectors) can be computationally expensive. Passing by reference only passes an alias (under the hood, a pointer), avoiding the overhead of copying.
3. **Cleaner Syntax:** Unlike pointers, references do not require dereferencing operators (`*`) or address-of operators (`&`) at the call site, making the code cleaner and easier to read.
---
### Syntax
To pass a parameter by reference, you declare the function parameter as a reference type by appending the ampersand symbol (`&`) to the data type:
```cpp
void functionName(DataType& parameterName);
```
When calling the function, you pass the variable normally:
```cpp
functionName(actualVariable);
```
---
### Code Example: Swapping Two Numbers
The classic example to demonstrate pass-by-reference is a swap function. In a pass-by-value setup, swapping parameters inside a function has no effect outside of it. By using references, we can swap the actual variables in the calling scope.
```cpp
#include
using namespace std;
// Function declaration using reference parameters
void swap(int& x, int& y);
int main ()
{
// Local variable declarations
int a = 100;
int b = 200;
cout << "Before swap, value of a: " << a << endl;
cout << "Before swap, value of b: " << b << endl;
/* Call the function to swap the values */
swap(a, b);
cout << "After swap, value of a: " << a << endl;
cout << "After swap, value of b: " << b << endl;
return 0;
}
// Function definition
void swap(int& x, int& y)
{
int temp;
temp = x; /* Save the value at address x */
x = y; /* Assign y to x */
y = temp; /* Assign temp (original x) to y */
return;
}
```
#### Output
When the above code is compiled and executed, it produces the following output:
```text
Before swap, value of a: 100
Before swap, value of b: 200
After swap, value of a: 200
After swap, value of b: 100
```
---
### Key Considerations
#### 1. Pass-by-Reference vs. Pass-by-Pointer
While both allow you to modify the original variable, they have distinct differences:
* **Nullability:** A pointer can be assigned `nullptr` (null), whereas a reference must always refer to a valid object.
* **Reassignment:** A pointer can be reassigned to point to a different variable. A reference is bound to its initializer permanently and cannot be rebound.
* **Syntax:** References use standard variable syntax, avoiding the visual clutter of `*` and `->` operators.
#### 2. Protecting Data with `const` References
If you want to pass a large object by reference to avoid copying costs, but you also want to guarantee that the function **cannot** modify the original object, you should use a **constant reference** (`const &`):
```cpp
void printLargeData(const MyLargeClass& data) {
// data.modify(); // Compiler Error: 'data' is read-only
cout << data.getName() << endl;
}
```
YouTip