Differences between C++ References and Pointers: When to Use References?

1. Basic Concepts: Understand “What It Is” First

In C++, both references and pointers relate to “variable addresses” or “aliases,” but they are fundamentally different:

  • Reference: Is an alias for a variable. It shares the same memory space as the original variable. It must be bound to an existing object during definition and cannot be redirected to another object once bound.
    For example: int a = 10; int& ref = a; Here, ref is an alias for a. Modifying ref is equivalent to modifying a.

  • Pointer: Is a variable that stores an address. It can point to the memory address of a variable or be nullptr (indicating no object is pointed to).
    For example: int a = 10; int* ptr = &a; Here, ptr stores the address of a, and *ptr accesses the value of a.

2. Core Differences: 5 Key Points to Distinguish

Comparison Reference Pointer
Syntax Uses & during definition (no extra space, e.g., int& ref = a;) Uses * and & during definition (occupies memory, e.g., int* ptr = &a;)
Nullability Cannot be nullptr (must bind to an object) Can be nullptr (no object pointed to)
Initialization Must be initialized during definition (e.g., int& ref = a;) Can be uninitialized (but usually assigned a valid address or nullptr)
Mutability Cannot be redirected after binding (fixed to one object) Can modify target anytime (e.g., ptr = &b;)
Dereferencing Direct use (e.g., ref = 20;) Requires * for dereferencing (e.g., *ptr = 20;)

3. Key Details: Common Mistakes for Beginners

  1. Reference Cannot Exist Alone
    References must bind to an object and cannot be “dangling” like pointers. For example: int& ref; is invalid; it must be written as int& ref = a;.

  2. Pointer Can Be “Null,” Reference Cannot
    Pointers can be nullptr (no valid target), e.g., int* ptr = nullptr;; references will cause an error if assigned nullptr.

  3. Size Difference
    - The size of a reference is the same as the type it references (e.g., int& is 4 bytes, same as int).
    - Pointer size is fixed (4 bytes on 32-bit systems, 8 bytes on 64-bit systems), independent of the pointed type.

4. Use Cases: When to Use Reference vs. Pointer?

Prefer Reference When:
1. Function Parameters: Avoid large object copying (e.g., void print(const string& s)). References do not copy the entire object, improving efficiency.
2. Returning Objects: Avoid copying large objects (e.g., string& getStr()).
3. Array/Container Aliases: Alias arrays or containers (e.g., vector<int>& v = vec;).
4. Overloading Operators: E.g., string& operator[](int index) (similar to C++ standard library array access).

Prefer Pointer When:
1. Dynamic Memory Management: Manually allocate/release memory (e.g., int* p = new int[10];).
2. Need to Modify Target: E.g., void swap(int* a, int* b) (function modifies pointer targets).
3. Returning Null Pointers for Failure: If a function may return no valid result, use a pointer to return nullptr (e.g., Node* findNode(int key)).
4. Dynamic Array/Container Access: Traverse arrays via pointers (e.g., int* p = arr; p++;).

5. Code Examples: More Intuitive Usage

Example 1: Modification Comparison Between Reference and Pointer

int a = 10;
int& ref = a;  // ref is an alias for a
int* ptr = &a; // ptr points to a's address

// Modifying ref/ptr is equivalent to modifying a
ref = 20;  // Equivalent to a = 20
*ptr = 30; // Equivalent to a = 30
cout << a << endl; // Output: 30 (both ref and ptr modified a)

Example 2: Immutability of Reference vs. Pointer

int x = 10, y = 20;
int& ref = x;  // ref can only bind to x
ref = y;       // Valid: ref modifies x to 20
// ref = &y;    // Error: Reference cannot be redirected!

int* ptr = &x;
ptr = &y;       // Valid: ptr now points to y
*ptr = 30;      // Modifies y to 30
cout << y << endl; // Output: 30

6. Summary: One-Sentence Takeaway

  • Reference: A “variable alias”—simple and safe, ideal for direct object access (avoids copying).
  • Pointer: A “variable storing an address”—flexible but requires manual management (e.g., null pointers, memory release), suitable for dynamic scenarios.

Beginner Tip: Prioritize references (safe and concise) and use pointers only when handling null values or dynamic memory.

(Note: The code in this article uses C++11 or later standards. Ensure your compiler supports references.)

Xiaoye