Menu
CoddyTech

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.

challenge icon

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 struct Counter với một thành viên int 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ệu COUNTER_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: 8

Tự 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;
}
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