Struct dưới dạng đối tượng
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 6 trên 61.
Trong các ngôn ngữ hướng đối tượng, đối tượng (object) là một thực thể kết hợp dữ liệu (trạng thái) với các hàm (function) thao tác trên dữ liệu đó (phương thức). C không có đối tượng tích hợp sẵn, nhưng ta có thể đạt được cùng một khái niệm bằng cách dùng struct và hàm.
Hãy xem struct là phần "dữ liệu" của một đối tượng. Nó lưu giữ trạng thái: các giá trị xác định đối tượng hiện đang như thế nào:
typedef struct {
int value;
} Counter;
Cấu trúc Counter này biểu diễn một thực thể có một trạng thái duy nhất: giá trị hiện tại của nó. Để tạo hành vi cho cấu trúc này, ta viết các hàm (function) nhận cấu trúc làm tham số:
void counter_increment(Counter *c) {
c->value++;
}
int counter_get(Counter *c) {
return c->value;
}
Các hàm này hoạt động như phương thức. Chúng thao tác cụ thể trên dữ liệu Counter. Bằng cách truyền struct vào các hàm, chúng ta mô phỏng cách các ngôn ngữ khác tự động xử lý khi bạn gọi counter.increment().
int main() {
Counter my_counter = {0};
counter_increment(&my_counter);
printf("%d\n", counter_get(&my_counter)); // In ra: 1
return 0;
}
Quy ước đặt tên typename_action (như counter_increment) giúp bạn sắp xếp code và làm rõ hàm (function) thuộc về struct nào. Mẫu này là nền tảng của lập trình hướng đối tượng trong C.
Thử thách
DễHãy tạo một module Counter đơn giản, xem struct như một đối tượng có hành vi. Bạn sẽ sắp xếp code trong ba tệp để thực hành cách gộp dữ liệu với các hàm thao tác trên dữ liệu đó.
Bạn sẽ tạo ba tệp:
counter.h: Tệp header khai báo structCountervới một thành viênint value. Đồng thời khai báo hai hàm hoạt động như “phương thức” của counter:counter_increment(nhận một con trỏ đến Counter và tăng giá trị của nó lên 1) vàcounter_get(nhận một con trỏ đến Counter và trả về giá trị hiện tại). Dùng include guard với ký hiệuCOUNTER_H.counter.c: Tệp mã nguồn triển khai cả hai hàm. Nhớ thêm tệp header.main.c: Tệp chính tạo một Counter, thực hiện các thao tác trên nó và hiển thị kết quả.
Bạn sẽ nhận hai đầu vào số nguyên: giá trị ban đầu của counter và số lần cần tăng giá trị.
Trong tệp chính, khởi tạo một Counter với giá trị ban đầu, rồi gọi counter_increment số lần đã chỉ định. Cuối cùng, dùng counter_get để lấy và in ra giá trị cuối cùng.
In kết quả theo định dạng này:
Final value: {result}Ví dụ, với giá trị ban đầu là 5 và tăng 3 lần, đầu ra sẽ là:
Final value: 8Tự làm thử
#include <stdio.h>
#include "counter.h"
int main() {
// Đọc đầu vào
int starting_value;
int num_increments;
scanf("%d", &starting_value);
scanf("%d", &num_increments);
// TODO: Tạo một Counter và khởi tạo bằng starting_value
// TODO: Gọi counter_increment số lần đã chỉ định
// TODO: Dùng counter_get để lấy giá trị cuối cùng và in ra
// Định dạng in ra: "Final value: {result}"
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