פונקציות 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
התבנית הזו מעניקה לך שליטה מלאה על אופן הגישה לנתונים: זהו הבסיס שעליו נבנה בשיעור הבא, כשנוסיף לוגיקת אימות לפונקציות ההגדרה.
אתגר
קלבוא נבנה מודול Score שמשתמש בתבנית של מצביע אטום עם פונקציות getter ו-setter. תיצור מעקב מוסתר אחר הניקוד, שבו קוד חיצוני יכול לקיים אינטראקציה עם הנתונים רק דרך הממשק הציבורי שתספק.
תיצור שלושה קבצים:
score.h: הממשק הציבורי שלך. הצהר על טיפוס אטוםScoreבאמצעות הצהרה מקדימה (ללא גוף של struct!). הצהר על הפונקציות הבאות:create_score: מקבלת מספר שלם עבור הנקודות ההתחלתיות ומחזירה מצביע ל-Scorefree_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;
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
4כימוס
המושג של מצביעים אטומיםהגדרת מבנים אטומיםפונקציות Get ו-Setאימות ב-Settersסיכום: הקופסה הסודית2אובייקטים ומתודות
מבנים כאובייקטיםמצביע 'Self'נכונות constמצביע לעומת ערךמתודות עזרחזרה: מנהל נקודות5פרויקט: חשבון בנק פשוט
הגדרת הפרויקטמימוש החשבוןתרגלו בעצמכם: קומפיילר C אונליין