C++ References and Pointers
C++ references and pointers both let you refer to another variable without copying it. A reference is an alias that must always refer to something, while a pointer stores an address and can be empty or changed.
References
A reference is declared with & and must be initialized. After that, using the reference is exactly like using the original variable.
#include <iostream>
int main() {
int level = 1;
int& alias = level;
alias = 5;
std::cout << level << '\n';
}5
Pointers
A pointer holds an address. & takes an address and * dereferences it. Use nullptr for "points to nothing".
#include <iostream>
int main() {
int value = 42;
int* ptr = &value;
std::cout << *ptr << '\n';
*ptr = 100;
std::cout << value << '\n';
int* empty = nullptr;
if (!empty) std::cout << "pointer is null\n";
}42 100 pointer is null
References vs Pointers in C++
- A reference cannot be null; a pointer can be nullptr.
- A reference cannot be reseated to refer to something else; a pointer can.
- References use normal syntax; pointers need * and ->.
- Prefer references for function parameters; use pointers when "no object" is a valid option.
- For owning heap memory, use smart pointers instead of raw pointers.
Pointers to Objects
With a pointer to an object, use -> to access members.
#include <iostream>
#include <string>
struct User {
std::string name;
int points;
};
void reward(User* u) {
if (u) u->points += 10;
}
int main() {
User me{"Naeem", 90};
reward(&me);
std::cout << me.name << ": " << me.points << '\n';
}Naeem: 100
Frequently asked questions
What is the difference between a reference and a pointer in C++?
A reference is a permanent alias that cannot be null. A pointer is a variable holding an address that can be null and can be changed to point elsewhere.
Why use nullptr instead of NULL?
nullptr has its own type (std::nullptr_t) and cannot be confused with the integer 0, which avoids overload ambiguities. Use nullptr in modern C++.
Should I use raw pointers in modern C++?
Raw pointers are fine for non-owning access. For owning dynamically allocated objects, use std::unique_ptr or std::shared_ptr.