ภาพรวม
Static Variables ภายใน Member Function (หรือฟังก์ชันทั่วไป) มีลักษณะพิเศษ:
- จัดสรรหน่วยความจำ เพียงครั้งเดียว ตลอดการรันโปรแกรม
- มี เพียง 1 ตัว แชร์ร่วมกันทุกครั้งที่เรียกฟังก์ชัน (รวมทุกออบเจ็กต์)
- Initialize แค่ครั้งแรกที่ผ่านบรรทัดการประกาศ
- ค่า Default คือ 0 (สำหรับ primitive types)
- มีอายุชีวิตจนโปรแกรมจบ (Program Lifetime)
ตัวอย่างโค้ด
#include <iostream>
using namespace std;
class Base {
public:
void func() {
static int a; // Default initialize = 0
static int b = 12; // Explicit initialize = 12
cout << "The default value of static variable a is: " << a;
cout << "\nThe value of static variable b is: " << b;
a++; b++; // แสดงว่าคงค่าระหว่างการเรียก
}
};
int main() {
Base obj1;
obj1.func(); // a=0, b=12
Base obj2;
obj2.func(); // a=1, b=13 (ค่าเพิ่มขึ้น!)
obj1.func(); // a=2, b=14 (ยังคงค่าเดิม)
return 0;
}
ผลลัพธ์
The default value of static variable a is: 0
The value of static variable b is: 12
The default value of static variable a is: 1
The value of static variable b is: 13
The default value of static variable a is: 2
The value of static variable b is: 14
รายละเอียดสำคัญ
- Shared across all objects: ไม่ใช่ต่อออบเจ็กต์ แตกต่างจาก Non-static Data Members
- Initialization thread-safe (C++11+): Compiler ใส่ guard code ป้องกัน race condition
- Scope: มองเห็นได้เฉพาะภายในฟังก์ชันนั้นๆ (Function Scope)
- Lifetime: Static Storage Duration (Program Lifetime)
กรณีการใช้งานทั่วไป
- Call Counter: นับจำนวนครั้งที่ฟังก์ชันถูกเรียก
- Caching/Memoization: เก็บผลลัพธ์ไว้ใช้ซ้ำ
- Singleton Instance: Meyers' Singleton Pattern
- One-time Initialization: ทำ initialization แค่ครั้งแรก
ตัวอย่าง Call Counter
void trackCalls() {
static int count = 0;
count++;
cout << "Function called " << count << " times\n";
}
ข้อควรระวัง
- ไม่ใช่ Thread-Local (ถ้าต้องการ ใช้
thread_local) - Destruction order ไม่แน่นอนข้าม Translation Units
- การทดสอบ (Unit Testing) ยาก เพราะสถานะคงค่าระหว่างเทส