תבנית בנאי
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C של Coddy. שיעור 12 מתוך 61.
בשפות כמו Java או C++, יוצרים אובייקטים באמצעות בנאים: פונקציות מיוחדות שמקצות זיכרון ומאתחלות שדות באופן אוטומטי. ל-C אין תכונה כזאת, אבל אפשר לדמות אותה באמצעות תבנית פשוטה: פונקציית create_.
פונקציית בנאי ב־C מבצעת בדרך כלל שלושה דברים: מקצה זיכרון באמצעות malloc, מאתחלת את כל השדות לערכים מתאימים ומחזירה מצביע לאובייקט החדש:
typedef struct {
char *name;
int age;
} Person;
Person *create_person(const char *name, int age) {
Person *p = malloc(sizeof(Person));
p->name = malloc(strlen(name) + 1);
strcpy(p->name, name);
p->age = age;
return p;
}
הפונקציה מחזירה מצביע כי האובייקט נמצא בערימה ולא במחסנית. המשמעות היא שהוא ממשיך להתקיים גם אחרי שהפונקציה חוזרת, ואפשר להעביר אותו בחופשיות. הקוד הקורא משתמש בו כך:
Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);
שימו לב לאופן שבו הבנאי מטפל בכל הפרטים המסורבלים: הקצאת המבנה, הקצאת מקום למחרוזת והעתקת הנתונים. הקוד שקורא לו רק מספק את הערכים הראשוניים ומקבל אובייקט מוכן לשימוש. כך לוגיקת היצירה מרוכזת במקום אחד, והקוד שלכם נקי יותר ופחות מועד לטעויות.
אתגר
קלבואו נבנה מודול Book שמשתמש בתבנית הבנאי כדי ליצור אובייקטים של ספרים בערימה. תתרגלו לכתוב פונקציית create_ שמטפלת בכל הקצאת הזיכרון והאתחול, ומחזירה מצביע מוכן לשימוש.
תיצרו שלושה קבצים:
book.h: הכריזו על מבנהBookעם שני איברים:char *title(מצביע למחרוזת שהוקצתה באופן דינמי) ו-int pages. הכריזו גם על פונקציית בנאיcreate_bookשמקבלת מחרוזת כותרת ומספר עמודים, ולאחר מכן מחזירה מצביע ל-Book חדש שנוצר. השתמשו בשומרי הכללה עם הסמלBOOK_H.book.c: ממשו את הפונקציהcreate_book. הבנאי שלכם צריך להקצות זיכרון למבנה Book עצמו, לאחר מכן להקצות זיכרון נפרד למחרוזת הכותרת (זכרו להביא בחשבון את תו סיום המחרוזת), להעתיק את הכותרת לזיכרון החדש, להגדיר את השדה pages ולהחזיר את המצביע ל-Book החדש.main.c: השתמשו בבנאי שלכם כדי ליצור ספר ולהציג את המידע שלו.
תקבלו שני קלטים: כותרת הספר (מחרוזת) ו-מספר העמודים (מספר שלם).
בקובץ הראשי שלכם, השתמשו ב-create_book כדי ליצור ספר חדש עם הערכים הנתונים, ולאחר מכן הדפיסו את המידע שלו בפורמט הבא:
Title: {title}
Pages: {pages}לדוגמה, עבור הקלטים The C Programming Language ו-272, הפלט יהיה:
Title: The C Programming Language
Pages: 272זכרו שהבנאי שלכם מרכז את כל לוגיקת היצירה: הקוד הקורא פשוט מספק את הערכים ההתחלתיים ומקבל אובייקט מאותחל במלואו שמוכן לשימוש.
נסו בעצמכם
#include <stdio.h>
#include <stdlib.h>
#include "book.h"
int main() {
char title[256];
int pages;
// קרא את הקלט
fgets(title, sizeof(title), stdin);
// הסר את תו השורה החדשה אם הוא קיים
for (int i = 0; title[i]; i++) {
if (title[i] == '\n') {
title[i] = '\0';
break;
}
}
scanf("%d", &pages);
// TODO: השתמש ב-create_book כדי ליצור ספר חדש עם הערכים שסופקו
// TODO: הדפס את פרטי הספר בפורמט הנדרש:
// כותרת: {title}
// עמודים: {pages}
// TODO: אל תשכח לשחרר את הזיכרון שהוקצה בסיום
return 0;
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
4כימוס
המושג של מצביעים אטומיםהגדרת מבנים אטומיםפונקציות Get ו-Setאימות ב-Settersסיכום: הקופסה הסודית2אובייקטים ומתודות
מבנים כאובייקטיםמצביע 'Self'נכונות constמצביע לעומת ערךמתודות עזרחזרה: מנהל נקודות5פרויקט: חשבון בנק פשוט
הגדרת הפרויקטמימוש החשבוןתרגלו בעצמכם: קומפיילר C אונליין