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.
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ểuScoremờ đụ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 Scorefree_score: nhận con trỏ đến Score và giải phóng bộ nhớscore_get_points: hàm getter nhậnconst Score *và trả về điểm hiện tạiscore_set_points: hàm setter nhậnScore *và một số nguyên, rồi cập nhật giá trị điểm
SCORE_H.score.c: Định nghĩastruct Scorethự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ỏconstvì 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}
FreedVí dụ, với đầu vào 100 và 250, đầu ra sẽ là:
Initial: 100
Updated: 250
FreedLư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;
}
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
1Kiến thức cơ bản về lập trình mô-đun
Tệp tiêu đềInclude guardTệp mã nguồnHàm staticÔn tập: Máy tính mô-đun4Tính đóng gói
Khái niệm con trỏ mờĐịnh nghĩa struct mờHàm truy xuất và hàm gánKiểm tra tính hợp lệ trong hàm gánÔn tập: Hộp bí mật2Đối tượng và phương thức
Struct dưới dạng đối tượngCon trỏ 'Self'Tính đúng đắn của constCon trỏ và giá trịPhương thức hỗ trợÔn tập: trình quản lý Point5Dự án: Tài khoản ngân hàng đơn giản
Thiết lập dự ánTriển khai tài khoản3Vòng đời đối tượng
Mẫu hàm khởi tạoMẫu hàm hủyKhởi tạo trên ngăn xếpSao chép sâuÔn tập: lớp bao bọc chuỗi6Kế thừa bằng cách kết hợp
Nhúng structQuy tắc thành viên đầu tiênTruy cập thành viên lớp chaUpcastingÔn tập: hệ phân cấp hình dạngTự luyện tập: Trình biên dịch C online