Menu
Coddy logo textTech

הדמיית מתודות

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

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

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

typedef void (*ActionFunc)(void);

typedef struct {
    const char* name;
    ActionFunc execute;
} Action;

בעת יצירת מופעים, מחברים פונקציות שונות לכל אחד מהם:

void say_hello(void) {
    printf("Hello!\n");
}

void say_goodbye(void) {
    printf("Goodbye!\n");
}

int main() {
    Action greet = { "Greet", say_hello };
    Action farewell = { "Farewell", say_goodbye };
    
    greet.execute();    // פלט: Hello!
    farewell.execute(); // פלט: Goodbye!
    return 0;
}

גם greet וגם farewell הם מאותו סוג (Action), ובכל זאת קריאה ל־execute על כל אחד מהם מניבה תוצאות שונות לחלוטין. המבנה לא רק מכיל נתונים. הוא מכיל התנהגות שמשתנה בין מופעים.

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

challenge icon

אתגר

קל

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

תיצרו שני קבצים כדי לארגן את הקוד שלכם:

  • speaker.h: הגדירו סוג של מצביע לפונקציה בשם SpeakFunc שאינו מקבל פרמטרים ואינו מחזיר ערך. לאחר מכן הגדירו מבנה Speaker שמכיל name (מסוג const char*) ומצביע לפונקציה speak מסוג SpeakFunc.
  • main.c: כללו את קובץ הכותרת שלכם וממשו שלוש פונקציות דיבור שונות:
    • bark: מדפיסה Woof!
    • meow: מדפיסה Meow!
    • chirp: מדפיסה Chirp!
    לאחר מכן צרו שני מופעים של Speaker, שכל אחד מהם מחובר לפונקציה אחרת בהתאם לקלט, וקראו למתודות speak שלהם כדי לראות פולימורפיזם בפעולה.

התוכנית שלכם תקבל שני קלטים: סוג הדובר הראשון (1 עבור bark, 2 עבור meow, 3 עבור chirp) וסוג הדובר השני (גם 1, 2 או 3).

צרו שני מופעים של Speaker. תוכלו לקרוא להם בכל שם שתרצו (למשל "Dog", "Cat", "Bird" או פשוט "Speaker1", "Speaker2"). חברו כל אחד מהם לפונקציה המתאימה לפי קוד הקלט שלו, ואז קראו ל-speak בכל מופע לפי הסדר.

פלט לדוגמה כאשר הסוג הראשון הוא 1 והסוג השני הוא 2:

Woof!
Meow!

פלט לדוגמה כאשר הסוג הראשון הוא 3 והסוג השני הוא 3:

Chirp!
Chirp!

התובנה המרכזית כאן היא ששני הדוברים הם מאותו סוג Speaker, ובכל זאת מפיקים פלטים שונים מפני שלכל אחד מהם מוקצית פונקציה אחרת לחבר speak. זכרו להשתמש בשומרי הכללה בקובץ הכותרת שלכם.

נסו בעצמכם

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

// TODO: ממשו את הפונקציה bark שמדפיסה "Woof!"

// TODO: ממשו את הפונקציה meow שמדפיסה "Meow!"

// TODO: ממשו את הפונקציה chirp שמדפיסה "Chirp!"

int main() {
    int type1, type2;
    scanf("%d", &type1);
    scanf("%d", &type2);
    
    // TODO: צרו שני מופעים של Speaker
    
    // TODO: הגדירו את הפונקציה speak של הרמקול הראשון בהתאם ל-type1
    // (1 = bark, 2 = meow, 3 = chirp)
    
    // TODO: הגדירו את הפונקציה speak של הרמקול השני בהתאם ל-type2
    // (1 = bark, 2 = meow, 3 = chirp)
    
    // TODO: קראו ל-speak בכל אחד מהרמקולים לפי הסדר
    
    return 0;
}
quiz iconבחנו את עצמכם

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

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

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