Menu
CoddyTech

Hàm truy xuất và hàm gán

Thuộc phần Lập trình hướng đối tượng trong hành trình C của Coddy. Bài học 19 trên 61.

Với con trỏ opaque (opaque pointer), các thành viên của struct sẽ bị ẩn khỏi code bên ngoài. Nhưng nếu code bên ngoài không thể truy cập dữ liệu trực tiếp, làm thế nào để đọc hoặc sửa đổi dữ liệu đó? Câu trả lời là các hàm getter và setter (getter and setter functions): giao diện công khai giúp truy cập dữ liệu riêng tư một cách có kiểm soát.

Hàm getter trả về giá trị của một thành viên ẩn:

// counter.h
int counter_get_value(const Counter *c);

// counter.c
int counter_get_value(const Counter *c) {
    return c->value;
}

Hàm setter thay đổi một thành viên ẩn:

// counter.h
void counter_set_value(Counter *c, int new_value);

// counter.c
void counter_set_value(Counter *c, int new_value) {
    c->value = new_value;
}

Lưu ý quy ước đặt tên: thêm tiền tố là tên kiểu vào các hàm (function) (counter_) để tránh xung đột và giúp API rõ ràng. Các hàm getter dùng con trỏ const vì chúng không sửa đổi đối tượng.

Giờ đây, code bên ngoài có thể tương tác an toàn với dữ liệu ẩn:

// main.c
Counter *c = create_counter(10);
printf("%d\n", counter_get_value(c));  // 10
counter_set_value(c, 25);
printf("%d\n", counter_get_value(c));  // 25

Mẫu này giúp bạn kiểm soát hoàn toàn cách truy cập dữ liệu. Đây là nền tảng để mình phát triển trong bài học tiếp theo, khi thêm logic xác thực vào các hàm setter.

challenge icon

Thử thách

Dễ

Hãy cùng xây dựng một module Score sử dụng mẫu con trỏ mờ đục (opaque pointer pattern) với các hàm getter và setter. Bạn sẽ tạo một bộ theo dõi điểm số ẩn, để code bên ngoài chỉ có thể tương tác với dữ liệu thông qua giao diện công khai mà bạn cung cấp.

Bạn sẽ tạo ba tệp:

  • score.h: Giao diện công khai. Khai báo kiểu Score mờ đục bằng khai báo trước, không có phần thân struct! Khai báo các hàm sau:
    • create_score: nhận một số nguyên làm điểm ban đầu và trả về con trỏ đến Score
    • free_score: nhận con trỏ đến Score và giải phóng bộ nhớ
    • score_get_points: hàm getter nhận const Score * và trả về điểm hiện tại
    • score_set_points: hàm setter nhận Score * và một số nguyên, rồi cập nhật giá trị điểm
    Dùng các macro bảo vệ include với ký hiệu SCORE_H.
  • score.c: Định nghĩa struct Score thực tế với một thành viên ẩn duy nhất: int points. Triển khai cả bốn hàm. Hàm getter cần trả về giá trị ẩn, còn hàm setter cần cập nhật giá trị đó. Hãy nhớ rằng getter dùng con trỏ const vì chúng không sửa đổi đối tượng.
  • main.c: Minh họa module bằng cách tạo một điểm số, đọc giá trị, sửa đổi giá trị bằng setter, rồi đọc lại.

Bạn sẽ nhận hai đầu vào: điểm ban đầu (một số nguyên) và giá trị điểm mới (một số nguyên) cần gán.

Trong tệp chính, hãy tạo một Score với điểm ban đầu, in giá trị hiện tại bằng getter, cập nhật giá trị bằng setter với giá trị mới, in giá trị đã cập nhật, sau đó giải phóng điểm số và in thông báo xác nhận.

In đầu ra theo định dạng sau:

Initial: {points}
Updated: {points}
Freed

Ví dụ, với đầu vào 100 và 250, đầu ra sẽ là:

Initial: 100
Updated: 250
Freed

Lưu ý rằng main.c không thể truy cập trực tiếp vào points. Code phải thông qua các hàm getter và setter của bạn. Đây là tính đóng gói trong thực tế: bạn kiểm soát chính xác cách đọc và sửa đổi dữ liệu ẩn.

Tự làm thử

#include <stdio.h>
#include "score.h"

int main() {
    int initial_points, new_points;
    scanf("%d", &initial_points);
    scanf("%d", &new_points);
    
    // TODO: Tạo Score với initial_points
    
    // TODO: Dùng getter để in ra giá trị ban đầu
    // Định dạng: "Initial: {points}"
    
    // TODO: Dùng setter để cập nhật điểm bằng new_points
    
    // TODO: Dùng getter để in ra giá trị sau khi cập nhật
    // Định dạng: "Updated: {points}"
    
    // TODO: Giải phóng score và in ra "Freed"
    
    return 0;
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch C online