הגדרת מבנים אטומים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C של Coddy. שיעור 18 מתוך 61.
עכשיו, לאחר שהבנת את המושג של מצביעים אטומים, בוא נראה איך משלימים את התבנית. קובץ הכותרת מצהיר שקיים טיפוס, אבל קובץ המקור הוא המקום שבו מגדירים מה באמת נמצא בתוכו.
הנה ההגדרה המלאה. ראשית, קובץ הכותרת עם ההצהרה המקדימה בלבד:
// counter.h
#ifndef COUNTER_H
#define COUNTER_H
typedef struct Counter Counter; // טיפוס לא שלם
Counter *create_counter(int start);
void free_counter(Counter *c);
#endif
לאחר מכן, קובץ המקור מכיל את ההגדרה בפועל של המבנה:
// counter.c
#include "counter.h"
#include <stdlib.h>
struct Counter {
int value; // מוסתר מבחוץ!
int step;
};
Counter *create_counter(int start) {
Counter *c = malloc(sizeof(Counter));
c->value = start;
c->step = 1;
return c;
}
void free_counter(Counter *c) {
free(c);
}
הנקודה העיקרית: struct Counter { ... } מופיע רק בקובץ .c. כל קובץ שכולל את counter.h יודע ש־Counter קיים, אבל אינו יכול לראות את value או את step. ניסיון לכתוב c->value בתוך main.c יגרום לשגיאת קומפילציה: האיברים באמת אינם גלויים.
ההפרדה הזאת היא הבסיס לאנקפסולציה ב-C. השלב הבא הוא לספק גישה מבוקרת באמצעות פונקציות getter ו-setter.
אתגר
קלבואו נבנה מודול Timer שמדגים את תבנית המצביע האטום. תתרגלו להסתיר את הגדרת המבנה בתוך קובץ המקור, כך שהחברים הפנימיים שלו יהיו בלתי נראים לחלוטין לכל קוד שמשתמש במודול שלכם.
תיצרו שלושה קבצים:
timer.h: זהו הממשק הציבורי שלכם. הכריזו על טיפוס אטוםTimerבאמצעות הצהרה מקדימה בלבד: בלי גוף של מבנה כאן! הכריזו גם על שתי פונקציות:create_timer(מקבלת מספר שלם של שניות ומחזירה מצביע ל-Timer) ו-free_timer(מקבלת מצביע ל-Timer ומשחררת את המשאבים). השתמשו בשומרי הכללה עם הסמלTIMER_H.timer.c: כאן נמצא הסוד. הגדירו אתstruct Timerבפועל עם שני חברים מוסתרים:int secondsו-int running(השתמשו ב-1 לציון פועל, וב-0 לציון עצור). ממשו את הבנאי שלכם כך שיקצה זיכרון למבנה, יאתחל אתsecondsלערך שסופק, ויקבע אתrunningל-1. ממשו את ההורס כך שישחרר את הזיכרון.main.c: השתמשו במודול Timer שלכם כדי ליצור טיימר ולאשר שהוא נוצר בהצלחה. מכיוון שחברי המבנה מוסתרים, אינכם יכולים לגשת אליהם ישירות. זו בדיוק המטרה! פשוט הדפיסו הודעה שמאשרת את היצירה, ואז שחררו את הטיימר והדפיסו הודעה על הניקוי.
תקבלו קלט אחד: מספר השניות (מספר שלם) לאתחול הטיימר.
בקובץ main שלכם, צרו טיימר עם ערך השניות שסופק. הדפיסו הודעת יצירה, ואז שחררו את הטיימר והדפיסו אישור.
הדפיסו את הפלט בפורמט הבא:
Timer created
Timer freedהתובנה החשובה כאן היא ש-main.c יכול לעבוד עם מצביעי Timer, אך אין לו דרך לגשת ישירות אל seconds או אל running. ניסיון לכתוב t->seconds בתוך main.c יגרום לשגיאת מהדר, מפני שגוף המבנה מוגדר רק בתוך timer.c. זוהי כמסות אמיתית: פרטי המימוש מוסתרים לחלוטין מהמשתמשים במודול שלכם.
נסו בעצמכם
#include <stdio.h>
#include "timer.h"
int main() {
int seconds;
scanf("%d", &seconds);
// TODO: צור טיימר עם ערך השניות שסופק
// TODO: הדפס "Timer created"
// TODO: שחרר את הטיימר
// TODO: הדפס "Timer freed"
return 0;
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
4כימוס
המושג של מצביעים אטומיםהגדרת מבנים אטומיםפונקציות Get ו-Setאימות ב-Settersסיכום: הקופסה הסודית2אובייקטים ומתודות
מבנים כאובייקטיםמצביע 'Self'נכונות constמצביע לעומת ערךמתודות עזרחזרה: מנהל נקודות5פרויקט: חשבון בנק פשוט
הגדרת הפרויקטמימוש החשבוןתרגלו בעצמכם: קומפיילר C אונליין