Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

Reference Variable ใน C++ คืออะไร?

ภาพรวม

Reference Variable (ตัวแปรอ้างอิง) คือชื่อเรียกอื่น (Alias) ของตัวแปรที่มีอยู่แล้ว ไม่ใช่ตัวแปรใหม่ ไม่มีหน่วยความจำแยกต่างหาก การดำเนินการกับ Reference คือการดำเนินการกับตัวแปรต้นฉบับโดยตรง

คุณสมบัติหลัก

  • ต้อง Initialize ตอนประกาศ (ไม่สามารถประกาศแยกได้)
  • ไม่สามารถเปลี่ยนอ้างอิงไปตัวแปรอื่นได้ (Re-bind ไม่ได้)
  • ไม่สามารถเป็น NULL ได้ (ต้องอ้างอิง Object จริงเสมอ)
  • ใช้ Operator & ในการประกาศ
  • Syntax: Type& refName = existingVar;

ตัวอย่างพื้นฐาน

#include <iostream>
using namespace std;

int main() {
    int a = 8;
    int& b = a;  // b เป็น Reference ของ a
    
    cout << "The variable a: " << a << "\n";
    cout << "The reference variable b: " << b << "\n";
    
    b = 20;  // เปลี่ยนค่าผ่าน Reference
    cout << "After b = 20:\n";
    cout << "a = " << a << "\n";  // a กลายเป็น 20 ด้วย!
    cout << "b = " << b << "\n";
    
    return 0;
}

ผลลัพธ์

The variable a: 8
The reference variable b: 8
After b = 20:
a = 20
b = 20

ประเภทของ References

1. Lvalue Reference (Classic) - Type&


int x = 10;
int& ref = x;        // OK
int& ref2 = 20;      // ❌ Error: Temporary (Rvalue) - ต้องเป็น const
const int& cref = 20; // OK: const lvalue reference binds to temporary

2. Rvalue Reference (C++11) - Type&&


int&& rref = 20;           // OK: Bind to Temporary
int&& rref2 = x;           // ❌ Error: x is Lvalue
int&& rref3 = std::move(x); // OK: Cast Lvalue to Rvalue

3. Forwarding Reference (Universal Reference) - T&& ใน Template


template
void func(T&& param) {  // Forwarding Reference (ไม่ใช่ Rvalue Ref เสมอไป)
    // Perfect Forwarding
    std::forward(param);
}

การใช้งานหลัก

1. Function Parameters (Pass by Reference)


// Pass by Reference - หลีกเลี่ยง Copy, สามารถ Modify ได้
void swap(int& a, int& b) {
    int temp = a; a = b; b = temp;
}

// Pass by Const Reference - หลีกเลี่ยง Copy, Read-Only
void print(const string& s) {
    cout << s;  // ไม่ Copy String
}

2. Return by Reference


// Return Reference to Existing Object (Static/Global/Member)
int& getElement(vector& v, size_t index) {
    return v[index];  // Reference to Element in Vector
}

// ❌ Dangerous: Return Reference to Local
int& badFunc() {
    int local = 10;
    return local;  // Dangling Reference! UB!
}

3. Range-based For Loop


vector vec = {1, 2, 3};
for (int& x : vec) {      // Reference - Modify Original
    x *= 2;
}
for (const int& x : vec) { // Const Reference - Read Only, No Copy
    cout << x << " ";
}

Reference vs Pointer

คุณสมบัติReference (T&)Pointer (T*)
Syntaxint& r = x;int* p = &x;
Nullไม่ได้ (Always Valid)ได้ (nullptr)
Reassignmentไม่ได้ (Bind Once)ได้ (Point to Elsewhere)
DereferenceImplicit (Auto)Explicit (*p)
Memory Overheadไม่มี (Alias)มี (Pointer Size)
Array/Pointer Arithmeticไม่ได้ได้

Best Practices

  1. Default to Pass by Const Reference สำหรับ Parameters (ยกเว้น Small Types: int, char, pointers)
  2. ใช้ std::move / Rvalue References สำหรับ Move Semantics
  3. ไม่ Return Reference to Local Variables
  4. ใช้ References สำห Operator Overloading (operator=, operator[], etc.)
  5. C++20: ใช้ std::span แทน Pointer+Size สำหรับ Array Views