Menu
CoddyTech

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.

challenge icon

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úc Person vớ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úc Employee, nhúng Person làm thành viên đầu tiên và thêm trường employee_id (số nguyên).
  • types.c: Cài đặt một hàm (function) có tên print_employee, nhận một con trỏ đến Employee và 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ến Employee, 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: 1001

Trong đó, 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;
}
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