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

Static Member Variables ใน C++ และการ Initialize

ภาพรวม

Static Member Variables ใน C++ ถูกประกาศด้วยคีย์เวิร์ด static ภายในคลาส มีคุณสมบัติ:

  • มีเพียง 1 ตัว ในหน่วยความจำ แชร์ร่วมกันทุกออบเจ็กต์ของคลาส
  • ไม่ได้อยู่ภายในออบเจ็กต์ (Non-object member)
  • ต้อง Define และ Initialize นอกคลาส (Definition) ใน Global Scope
  • ถ้าไม่ Initialize จะได้ค่า 0 อัตโนมัติ (Zero-initialization)
  • มีอายุชีวิตตลอดโปรแกรม (Static Storage Duration)

ตัวอย่างโค้ด

#include <iostream>
using namespace std;

class Demo {
public:
    static int num;           // Declaration (ในคลาส)
    
    void display() {
        cout << "The value of the static member variable num is: " << num;
    }
};

// Definition + Initialization (นอกคลาส - ต้องมีบรรทัดนี้!)
int Demo::num = 100;

int main() {
    Demo obj1, obj2, obj3;
    obj1.display();  // แสดง 100
    
    Demo::num = 200;  // เปลี่ยนค่าผ่านชื่อคลาส
    obj2.display();  // แสดง 200 (obj1, obj3 เห็นค่าใหม่ด้วย)
    
    return 0;
}

ผลลัพธ์

The value of the static member variable num is: 100
The value of the static member variable num is: 200

รายละเอียดการ Initialize

  1. In-class initialization (C++11): เฉพาะ static const integral หรือ constexpr
    class A {
        static const int MAX = 100;      // OK (const integral)
        static constexpr double PI = 3.14; // OK (constexpr)
        static int count = 0;             // Error! (Non-const)
    };
  2. Out-of-class definition (จำเป็นสำหรับ Non-const):
    int Demo::num = 100;  // ใน .cpp file
  3. Inline Static Members (C++17): Define ได้ในคลาสเลย
    class Modern {
        inline static int count = 0;  // C++17 - ไม่ต้อง define นอกคลาส
    };

กรณีการใช้งานทั่วไป

  • Object Counter: นับจำนวนออบเจ็กต์ที่สร้าง/ทำลาย
  • Shared Configuration: การตั้งค่าร่วมกัน (เช่น Log Level, Cache Size)
  • Factory/Registry: เก็บรายการออบเจ็กต์ที่สร้าง
  • Singleton Instance Pointer: Meyers' Singleton

ตัวอย่าง Object Counter


class Tracked {
    inline static int count = 0;  // C++17
public:
    Tracked() { count++; cout << "Created: " << count << "\n"; }
    ~Tracked() { count--; cout << "Destroyed: " << count << "\n"; }
    static int getCount() { return count; }
};

ข้อควรระวัง

  • Initialization Order Fiasco: Static members ในไฟล์ต่างๆ อาจ initialize ในลำดับผิด
  • Thread Safety: การเข้าถึงพร้อมกันต้องใช้ Mutex/Atomic
  • Destruction Order: ทำลายในลำดับกลับกันกับการสร้าง (ใน TU เดียวกัน)