Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Static Data Members trong C++

Static data member là thành viên dữ liệu của class được khai báo với từ khóa static. Chỉ có một bản sao duy nhất chung cho tất cả object của class.

Đặc điểm

  • Chia sẻ bởi tất cả instance của class
  • Khởi tạo một lần (trước main, hoặc lần đầu dùng)
  • Phải định nghĩa ngoài class (trừ C++17 inline)
  • Truy cập qua ClassName::member hoặc obj.member
  • Lifetime: suốt chương trình (static storage duration)

Cú pháp

class MyClass {
    static int count; // Khai báo (declaration)
};

// Định nghĩa (definition) - BẮT BUỘC trong 1 file .cpp
int MyClass::count = 0; // Khởi tạo mặc định 0

C++17: Inline Static Member (Không cần định nghĩa ngoài)

class MyClass {
    static inline int count = 0; // Định nghĩa ngay tại chỗ
    static inline const int MAX = 100; // const integral có thể init tại chỗ từ C++11
};

Ví dụ: Đếm số object được tạo

#include <iostream>
#include <string>
using namespace std;

class Student {
private:
    int rollNo;
    string name;
    int marks;
    
public:
    static int objectCount; // Khai báo
    
    Student() { objectCount++; } // Constructor tăng counter
    
    void getData() {
        cout << "Roll: "; cin >> rollNo;
        cout << "Name: "; cin >> name;
        cout << "Marks: "; cin >> marks;
    }
    
    void putData() const {
        cout << "Roll: " << rollNo << ", Name: " << name << ", Marks: " << marks << '\n';
    }
};

// Định nghĩa static member (trước C++17)
int Student::objectCount = 0;

int main() {
    Student s1, s2, s3;
    s1.getData(); s1.putData();
    s2.getData(); s2.putData();
    s3.getData(); s3.putData();
    
    cout << "Tổng object: " << Student::objectCount << endl; // 3
    return 0;
}

Kết quả mẫu

Roll: 1
Name: Mark
Marks: 78
Roll: 1, Name: Mark, Marks: 78
...
Tổng object: 3

Static const member (C++11)

class Config {
    static const int MAX_SIZE = 100; // Có thể init tại chỗ (integral type)
    static constexpr double PI = 3.14159; // C++11: constexpr static
    // static string DEFAULT_NAME = "default"; // LỖI: non-integral cần định nghĩa ngoài
};

// C++17: inline cho phép mọi kiểu
class Config17 {
    static inline std::string DEFAULT_NAME = "default"; // OK
};

Static member function

  • Không có this pointer
  • Chỉ truy cập được static member khác
  • Gọi qua Class::func()
class Math {
public:
    static int add(int a, int b) { return a + b; }
    static int getCount() { return count; }
private:
    static int count;
};
int Math::count = 0;

// Sử dụng
Math::add(2, 3); // 5
Math::getCount();

Use Cases

  • Counter: số object đang sống, ID tự động
  • Shared resource: connection pool, cache, logger
  • Configuration: settings chung cho tất cả instance
  • Factory pattern: registry
  • Singleton: instance pointer static

Lưu ý

  • Không thể truy cập non-static member từ static function
  • Thread safety: khởi tạo static local (C++11) an toàn, nhưng static member initialization order across TU không đảm bảo
  • C++17: inline static giải quyết definition issue