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

Static Data Member Initialization ใน C++: การกำหนดค่าเริ่มต้นให้ Static Member

Static Data Member ใน C++ Class เป็นสมาชิกที่ร่วมกันใช้ระหว่างทุก Instance (Object) ของ Class นั้น ต้อง Define และ Initialize นอกจาก Class Definition (Definition) เพราะ Class Definition เป็นแค่ Declaration

Syntax และกฎ


class MyClass {
    static int count;        // Declaration (ใน Class)
    static const int MAX = 100; // const integral: Initialize ใน Class ได้ (C++11)
};

// Definition + Initialization (ใน Global Scope, นอก Class) - จำเป็นสำหรับ Non-const Static
int MyClass::count = 0;      // :: Scope Resolution Operator

ตัวอย่างสมบูรณ์: นับจำนวน Object

#include <iostream>

class MyClass {
private:
    static int objectCount; // Declaration
    
public:
    MyClass() { 
        ++objectCount; 
        std::cout << "Object created. Count: " << objectCount << '\n';
    }
    
    ~MyClass() { 
        --objectCount; 
        std::cout << "Object destroyed. Count: " << objectCount << '\n';
    }
    
    static int getCount() { return objectCount; }
};

// Definition & Initialization (ต้องอยู่ใน .cpp file ถ้าเป็น Multi-file Project)
int MyClass::objectCount = 0; 

int main() {
    std::cout << "Initial: " << MyClass::getCount() << '\n'; // 0
    
    MyClass obj1; // 1
    MyClass obj2; // 2
    {
        MyClass obj3; // 3
    } // obj3 destroyed -> 2
    
    std::cout << "Final: " << MyClass::getCount() << '\n'; // 2
}

Static Const Members: Special Rules

TypeInitialize ใน Class?Definition นอก Class?
static const int / enum✅ ได้ (C++11: Integral Constant Expression)❌ ไม่ต้อง (ถ้าไม่取 Address)
static const double / string / Class❌ ไม่ได้ (Pre-C++17)✅ ต้อง Define นอก Class
static constexpr (C++11)✅ ได้ (ทุก Literal Type)❌ ไม่ต้อง (Implicit Inline)
static inline (C++17)✅ ได้ (ทุก Type)❌ ไม่ต้อง (Inline Variable)

C++17 Inline Variables (Modern Way)


class ModernClass {
public:
    // Header-only Definition + Initialization (C++17)
    static inline int count = 0;           // Non-const
    static inline const double PI = 3.14159; // Const
    static inline std::string name = "Default"; // Complex Type
};
// ไม่ต้อง Define ใน .cpp อีกต่อไป!

การเข้าถึง

  • ผ่าน Class: MyClass::staticMember (Preferred)
  • ผ่าน Object: obj.staticMember (ทำงานได้แต่ไม่แนะนำ - 混淆)

ข้อระวัง

  • Static Member มีเพียง หนึ่ง Instance ต่อ Program (Shared Across All Objects)
  • Initialization Order Across Translation Units: Undefined (Static Initialization Order Fiasco) - ใช้ Function-local Static (Meyers Singleton) แทน
  • Thread Safety: Initialization ของ Function-local Static เป็น Thread-Safe (C++11) แต่ Class Static ไม่รับประกัน

สรุป

Static Data Member ต้อง Define/Initialize นอก Class (Pre-C++17) C++17 inline static ทำให้ Header-only Libraries ง่ายขึ้น ใช้ constexpr สำหรับ Compile-time Constants และพิจารณา Thread Safety สำหรับ Complex Initialization