Nhúng struct
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 28 trên 61.
Trong các ngôn ngữ hướng đối tượng như C++ hoặc Java, tính kế thừa cho phép một lớp có các thuộc tính từ lớp cha. C không có sẵn tính kế thừa, nhưng chúng ta có thể mô phỏng bằng một kỹ thuật gọi là composition: đặt một struct bên trong struct khác.
Ý tưởng rất đơn giản: nếu Child cần tất cả thuộc tính của Parent, ta nhúng cấu trúc Parent làm thành viên của Child.
typedef struct {
int id;
char name[50];
} Parent;
typedef struct {
Parent parent; // Cấu trúc lồng bên trong
int grade;
} Child;Ở đây, Child chứa mọi thứ mà Parent có, cùng với trường grade riêng. Đây là kiểu kết hợp: lớp con «có» một lớp cha thay vì «là» một lớp cha, nhưng hiệu quả tương tự như kế thừa (inheritance).
Để truy cập các thành viên của lớp cha thông qua một đối tượng lớp con, bạn dùng toán tử dấu chấm hai lần:
Child c;
c.parent.id = 101;
c.parent.name[0] = 'A';
c.grade = 5;Mẫu này tạo nền tảng để xây dựng hệ phân cấp kiểu dữ liệu trong C. Bằng cách đặt một struct cơ sở làm thành viên đầu tiên, chúng ta có thể sử dụng những kỹ thuật mạnh mẽ mà mình sẽ tìm hiểu trong các bài học tiếp theo.
Thử thách
DễHãy xây dựng một hệ thống quản lý nhân viên đơn giản để minh họa cách nhúng cấu trúc: nền tảng của tính kế thừa trong C.
Bạn sẽ tạo một hệ phân cấp, trong đó Employee chứa một Person. Điều này mô phỏng cách hoạt động của tính kế thừa: nhân viên “là một” người và có thêm thông tin liên quan đến công việc. Bằng cách nhúng cấu trúc Person bên trong Employee, bạn có tất cả thuộc tính của người đó cùng các trường dành riêng cho nhân viên.
Bạn sẽ sắp xếp code trong ba tệp:
types.h: Định nghĩa cả hai cấu trúc tại đây bằng các lệnh bảo vệ include. Trước tiên, tạo cấu trúcPersonvới hai trường:name(mảng ký tự gồm 50 ký tự) vàage(số nguyên). Sau đó, định nghĩa cấu trúcEmployee, nhúngPersonlàm thành viên đầu tiên và thêm trườngemployee_id(số nguyên).types.c: Cài đặt một hàm (function) có tênprint_employee, nhận một con trỏ đếnEmployeevà in ra thông tin của họ. Truy cập dữ liệu của người được nhúng bằng cú pháp nối dấu chấm và mũi tên mà bạn đã học.main.c: Tạo một biếnEmployee, gán giá trị cho tất cả các trường (bao gồm tên và tuổi của người được nhúng), rồi dùng hàm in của bạn để hiển thị thông tin.
Bạn sẽ nhận ba đầu vào: tên nhân viên (một chuỗi), tuổi của họ (một số nguyên) và mã nhân viên (một số nguyên).
Hàm print_employee cần in ra thông tin nhân viên theo định dạng sau:
Employee: Alice
Age: 28
ID: 1001Trong đó, Alice là tên, 28 là tuổi và 1001 là mã nhân viên trong các đầu vào của bạn.
Nhớ truy cập các thành viên của cấu trúc được nhúng thông qua thành viên cha. Ví dụ, để truy cập tên, trước tiên bạn cần đi qua thành viên person.
Tự làm thử
#include <stdio.h>
#include <string.h>
#include "types.h"
int main() {
// Đọc đầu vào
char name[50];
int age;
int employee_id;
fgets(name, 50, stdin);
name[strcspn(name, "\n")] = '\0'; // Xóa ký tự xuống dòng
scanf("%d", &age);
scanf("%d", &employee_id);
// TODO: Tạo một biến Employee
// TODO: Gán tên và tuổi cho person bên trong
// Gợi ý: Dùng strcpy để gán tên, truy cập qua employee.person.name
// TODO: Gán employee_id
// TODO: Gọi print_employee với con trỏ trỏ đến biến employee
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