0

static trong cpp

Tham khảo: https://www.sandordargo.com/blog/2021/07/07/2-ways-to-use-static-with-functions-cpp

Trong C++, static không chỉ có một nghĩa duy nhất - nó thay đổi hành vi tùy theo ngữ cảnh được sử dụng

1. static trong hàm (local variable)

Biến static trong hàm:

  • Chỉ khởi tạo một lần duy nhất
  • Giữ giá trị giữa các lần gọi hàm
#include <iostream>
using namespace std;

void counter() {
    static int count = 0; 
    count++;
    cout << count << endl;
}

int main() {
    counter(); // 1
    counter(); // 2
    counter(); // 3
}

2. static trong class

Biến static

  • Thuộc về class, không thuộc về object
  • Tất cả object dùng chung một biến
#include <iostream>
using namespace std;

class Test {
public:
    static int shared;
};

int Test::shared = 0; // phải định nghĩa bên ngoài

int main() {
    Test a, b;
    a.shared = 10;
    cout << b.shared; // 10
}

Hàm static

  • Không cần object để gọi.
  • Không có con trỏ this
  • Không thể thao tác với các biến thông thường trong class, vì biến thông thường cần phải khởi tạo object. Còn biến toàn cục (Global) or biến static thì không cần.

Điểm bạn đang cấn ở đây chính là "tư duy thiết kế" đằng sau nó: Tại sao trong C++ (và OOP nói chung), người ta lại sinh ra hàm static thay vì cứ gộp chung vào hàm bình thường?

Để hiểu ý nghĩa thực sự, hãy tách biệt hai khái niệm: "Cái riêng của một thực thể" và "Cái chung của một hệ thống".

Bản chất của Static (Thành viên tĩnh) Hàm bình thường (Non-static): Phải gắn liền với một đối tượng (object) cụ thể, có lúc nó sống, có lúc nó chết, mang dữ liệu riêng biệt.

Hàm tĩnh (Static): Nó mang ý nghĩa là quy luật, giới hạn, hoặc tiện ích chung của cả một nhóm đối tượng. Nó tồn tại xuyên suốt chương trình ngay cả khi bạn chưa tạo ra bất kỳ đối tượng nào.

Ví dụ minh họa: Hãy thử lấy ví dụ từ một hệ thống lưu trữ chia nhỏ dữ liệu thành các bucket.

Giả sử ta định nghĩa một class StorageBucket để quản lý các file chứa dữ liệu:

class StorageBucket {
private:
    int currentOffset; // Vị trí ghi hiện tại (32 KiB, 64 KiB...)
    static const int MAX_CAPACITY = 128 * 1024 * 1024; // 128 MiB cho mọi bucket

public:
    // 1. Hàm bình thường (Non-static) - CÁI RIÊNG
    int getOffset() const { return currentOffset; }

    // 2. Hàm tĩnh (Static) - CÁI CHUNG
    static int getStandardCapacity() { return MAX_CAPACITY; }
};

Sự khác biệt về ý nghĩa:

Nếu bạn muốn biết "Bucket số 5 đang ghi tới đâu rồi?", bạn bắt buộc phải tạo/mở cái bucket số 5 đó ra, rồi mới gọi bucket5.getOffset(). Hàm này không thể là static, vì mỗi bucket có một currentOffset khác nhau.

Nhưng nếu thuật toán quản lý của bạn cần biết "Giới hạn dung lượng tối đa của một bucket trong kiến trúc này là bao nhiêu để tính toán trước thuật toán chia nhỏ?", bạn không cần (và không nên) mất công tạo ra một StorageBucket ảo trên RAM chỉ để hỏi câu đó. Bạn chỉ cần gọi trực tiếp StorageBucket::getStandardCapacity(). Đó chính là ý nghĩa thực sự của hàm static: Cung cấp thông tin cấu trúc/luật lệ mà không cần tốn tài nguyên khởi tạo đối tượng.

#include <iostream>
using namespace std;

class Math {
public:
    static int add(int a, int b) {
        return a + b;
    }
};

int main() {
    int x = Math::add(2, 3); 
    cout << x << endl;
    
    return 0;
}

Hàm static int add(int a, int b) => Thực chất giống một hàm thông thường nhưng vì nằm trong class nên cần phải gọi bằng Nameclass::namefuncion()

3. static trong file

Biến global static

Ví dụ:

static int x = 10;
  • Chỉ có thể được sử dụng trong file này (internal linkage), file khác không thể thấy biến

Hàm static

Chỉ trong file khai báo hàm static thì mới có thể sử dụng hàm này.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí