Menu
Coddy logo textTech

פונקציות Get ו-Set

חלק מהיחידה תכנות מונחה עצמים במסלול ה-C של Coddy. שיעור 19 מתוך 61.

עם מצביעים אטומים, איברי המבנה מוסתרים מקוד חיצוני. אבל אם קוד חיצוני לא יכול לגשת ישירות לנתונים, איך קוראים אותם או משנים אותם? התשובה היא פונקציות getter ו־setter: ממשקים ציבוריים שמספקים גישה מבוקרת לנתונים פרטיים.

פונקציית גישה מחזירה את הערך של איבר מוסתר:

// counter.h
int counter_get_value(const Counter *c);

// counter.c
int counter_get_value(const Counter *c) {
    return c->value;
}

Setter משנה איבר מוסתר:

// counter.h
void counter_set_value(Counter *c, int new_value);

// counter.c
void counter_set_value(Counter *c, int new_value) {
    c->value = new_value;
}

שימו לב למוסכמת מתן השמות: הוסיפו לשמות הפונקציות את שם הטיפוס כתחילית (counter_) כדי למנוע התנגשויות ולהבהיר את ה-API. פונקציות גישה משתמשות במצביעי const מכיוון שהן אינן משנות את האובייקט.

כעת קוד חיצוני יכול לקיים אינטראקציה עם הנתונים המוסתרים בבטחה:

// main.c
Counter *c = create_counter(10);
printf("%d\n", counter_get_value(c));  // 10
counter_set_value(c, 25);
printf("%d\n", counter_get_value(c));  // 25

התבנית הזו מעניקה לך שליטה מלאה על אופן הגישה לנתונים: זהו הבסיס שעליו נבנה בשיעור הבא, כשנוסיף לוגיקת אימות לפונקציות ההגדרה.

challenge icon

אתגר

קל

בוא נבנה מודול Score שמשתמש בתבנית של מצביע אטום עם פונקציות getter ו-setter. תיצור מעקב מוסתר אחר הניקוד, שבו קוד חיצוני יכול לקיים אינטראקציה עם הנתונים רק דרך הממשק הציבורי שתספק.

תיצור שלושה קבצים:

  • score.h: הממשק הציבורי שלך. הצהר על טיפוס אטום Score באמצעות הצהרה מקדימה (ללא גוף של struct!). הצהר על הפונקציות הבאות:
    • create_score: מקבלת מספר שלם עבור הנקודות ההתחלתיות ומחזירה מצביע ל-Score
    • free_score: מקבלת מצביע ל-Score ומשחררת את הזיכרון
    • score_get_points: פונקציית getter שמקבלת const Score * ומחזירה את הנקודות הנוכחיות
    • score_set_points: פונקציית setter שמקבלת Score * ומספר שלם, ומעדכנת את ערך הנקודות
    השתמש בשומרי הכללה עם הסמל SCORE_H.
  • score.c: הגדר את struct Score הממשי עם איבר מוסתר יחיד: int points. ממש את כל ארבע הפונקציות. פונקציית ה-getter שלך צריכה להחזיר את הערך המוסתר, ופונקציית ה-setter שלך צריכה לעדכן אותו. זכור שפונקציות getter משתמשות במצביעים מסוג const, מכיוון שהן אינן משנות את האובייקט.
  • main.c: הדגם את המודול שלך באמצעות יצירת ניקוד, קריאת הערך שלו, שינויו באמצעות פונקציית ה-setter וקריאתו שוב.

תקבל שתי קלטים: את הנקודות ההתחלתיות (מספר שלם) ואת ערך הנקודות החדש (מספר שלם) שיש להציב.

בקובץ main שלך, צור Score עם הנקודות ההתחלתיות, הדפס את הערך הנוכחי באמצעות פונקציית ה-getter, עדכן אותו באמצעות פונקציית ה-setter עם הערך החדש, הדפס את הערך המעודכן, לאחר מכן שחרר את הניקוד והדפס אישור.

הדפס את הפלט בתבנית הזאת:

Initial: {points}
Updated: {points}
Freed

לדוגמה, עבור הקלטים 100 ו-250, הפלט יהיה:

Initial: 100
Updated: 250
Freed

שים לב ש-main.c אינו יכול לגשת ישירות ל-points. הוא חייב להשתמש בפונקציות ה-getter וה-setter שלך. זוהי אנקפסולציה בפעולה: אתה שולט בדיוק באופן שבו אפשר לקרוא את הנתונים המוסתרים ולשנות אותם.

נסו בעצמכם

#include <stdio.h>
#include "score.h"

int main() {
    int initial_points, new_points;
    scanf("%d", &initial_points);
    scanf("%d", &new_points);
    
    // TODO: צרו Score עם initial_points
    
    // TODO: הדפיסו את הערך ההתחלתי באמצעות פונקציית הגישה
    // פורמט: "Initial: {points}"
    
    // TODO: עדכנו את הניקוד באמצעות פונקציית העדכון עם new_points
    
    // TODO: הדפיסו את הערך המעודכן באמצעות פונקציית הגישה
    // פורמט: "Updated: {points}"
    
    // TODO: שחררו את הזיכרון של הניקוד והדפיסו "Freed"
    
    return 0;
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר C אונליין