References & Pass-by-reference
রেফারেন্স ও পাস বাই রেফারেন্স
1. What Is a Reference?
A reference is an alias — another name for an existing variable. Once bound, it can never refer to anything else. It cannot be null. It is the cleanest way C++ has to share a variable instead of copying it.
#include <iostream>
int main() {
int x = 10;
int& r = x; // r is another name for x
r = 42; // modifies x
std::cout << x << "\n"; // 42
}
2. Pass by Value vs Pass by Reference
#include <iostream>
void byValue(int n) { n = 99; } // modifies a copy
void byRef(int& n) { n = 99; } // modifies the original
int main() {
int a = 5, b = 5;
byValue(a); byRef(b);
std::cout << a << " " << b << "\n"; // 5 99
}
3. const T& — Read-only by Reference
For large objects (strings, vectors), copying is expensive. Pass const T& — no copy, no
mutation:
#include <iostream>
#include <string>
#include <vector>
void printAll(const std::vector<std::string>& v) {
for (const auto& s : v) std::cout << s << "\n";
}
int main() {
std::vector<std::string> cities = {"Dhaka", "Chittagong", "Sylhet"};
printAll(cities);
}
4. Reference vs Pointer
| Aspect | Reference | Pointer |
|---|---|---|
| Can be null | No | Yes (nullptr) |
| Rebindable | No | Yes |
| Syntax | r = x; | *p = x; |
| Address-of | Implicit | Explicit (&x) |
| Use when | Always available; share | Optional; complex ownership |
T& over T* unless you specifically need null or rebinding.
5. Returning References
You can return a reference to enable modification or to avoid copying — but never return a reference to a local!
int& smallest(int& a, int& b) {
return (a < b) ? a : b;
}
int main() {
int x = 7, y = 3;
smallest(x, y) = 0; // y is now 0
}
// DON'T DO THIS:
// int& bad() { int x = 5; return x; } // dangling reference!
6. Practice Problems
- Write
void swap(int& a, int& b).✨ Show Answer
void swap(int& a, int& b) { int t = a; a = b; b = t; } - Why is
const std::string&usually preferred overstd::stringin parameters?✨ Show Answer
Avoids copying the entire string content.
constensures the function won't modify it. Best of both: efficiency + safety. - Can a reference be rebound?
✨ Show Answer
No.
int& r = x; r = y;assignsy's value toxviar;rstill refers tox. - What's wrong with:
int& r;✨ Show Answer
References must be initialized at declaration. There is no "null reference".
- Write a function that doubles each element in a vector via reference.
✨ Show Answer
void doubleAll(std::vector<int>& v) { for (auto& x : v) x *= 2; } - Why is returning a local by reference a bug?
✨ Show Answer
The local is destroyed when the function returns. The reference would point to invalid memory — undefined behavior.
- Make this safe by reference:
void increment(int x) { x++; }✨ Show Answer
void increment(int& x) { x++; } - Can you have a vector of references?
✨ Show Answer
No —
std::vector<int&>is illegal. References aren't objects in their own right. Workaround:std::vector<std::reference_wrapper<int>>. - When is pass-by-value actually preferable?
✨ Show Answer
For small types (int, double, char) — passing by reference adds an indirection, while value passing fits in a register. Also when you'd copy anyway inside the function.
- Demonstrate that a reference doesn't introduce a new variable.
✨ Show Answer
int x = 5; int& r = x; std::cout << &x << " " << &r << "\n"; // same address - Difference between
const int&andint const&?✨ Show Answer
None — they are exactly the same.
constbinds left of the type when both are present. Style:const int&is more common. - Write
int& getElement(std::vector<int>& v, size_t i).✨ Show Answer
int& getElement(std::vector<int>& v, size_t i) { return v[i]; }Allows
getElement(v, 0) = 42; - What does
auto& x = v[0];do?✨ Show Answer
Binds
xas a reference tov[0]. Modifyingxmodifiesv[0]. Without&, you'd get a copy. - Pass by const reference vs by value — which is faster for
int?✨ Show Answer
Pass by value. An int fits in a register; passing a reference adds a memory indirection. For built-ins, by value wins.
- What does
void f(std::string s)do thatvoid f(const std::string& s)doesn't?✨ Show Answer
The first copies the caller's string. The second binds a reference (no copy). Use the first only when you need a modifiable local copy anyway.
- Show that
int& r = 5;doesn't compile.✨ Show Answer
5 is a temporary (rvalue). A non-const lvalue reference cannot bind to it.
const int& r = 5;is OK — const refs can extend a temporary's lifetime.
Summary
A reference is an alias — never null, never rebindable. Use T& to allow modification,
const T& to read without copying. Prefer references over pointers when you don't need null
or rebinding. Never return a reference to a local variable.