בנאים מאצילים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C++ של Coddy. שיעור 23 מתוך 104.
כשיש לך כמה בנאים שמשתפים לוגיקת אתחול משותפת, אפשר להשתמש בבנאים מאצילים כדי להימנע משכפול קוד. בנאי מאציל קורא לבנאי אחר של אותה מחלקה ברשימת האתחול שלו.
class Player {
std::string name;
int health;
int level;
public:
// הבנאי הראשי - מבצע את העבודה בפועל
Player(std::string n, int h, int lvl)
: name(n), health(h), level(lvl) {}
// מעביר את הביצוע לבנאי הראשי
Player(std::string n) : Player(n, 100, 1) {}
// גם בנאי ברירת המחדל מעביר את הביצוע
Player() : Player("Unknown") {}
};ההאצלה מתבצעת ברשימת האתחול באמצעות שם המחלקה ואחריו הארגומנטים. כשקוראים ל־Player(), היא מאצילה ל־Player(std::string), שבתורה מאצילה לבנאי בעל שלושת הפרמטרים. השרשרת מתבצעת מהבנאי היעד בחזרה לבנאי המקורי.
יש כלל חשוב אחד: לבנאי שמעביר את הבנייה לבנאי אחר אסור לכלול חברים נוספים ברשימת האתחול שלו. העברת הבנייה חייבת להיות הפריט היחיד:
class Item {
int id;
int value;
public:
Item(int i, int v) : id(i), value(v) {}
// שגיאה! אי אפשר לשלב האצלה עם אתחול שדות מחלקה
// Item(int i) : Item(i, 0), id(i) {}
// תקין - האצלה בלבד
Item(int i) : Item(i, 0) {}
};בנאים מאצילים עוזרים לרכז את לוגיקת האתחול במקום אחד, וכך מקלים על תחזוקת הקוד ומפחיתים את הסיכוי לשגיאות שנובעות מקוד כפול.
אתגר
קלבואו נבנה מערכת להגדרות חיבור, שתדגים כיצד בנאים מאצילים יכולים למנוע שכפול קוד באמצעות שרשור קריאות לבנאים.
תיצרו שני קבצים כדי לארגן את הקוד:
Connection.h: הגדירו מחלקה בשםConnectionשמייצגת חיבור רשת עם אפשרויות הגדרה שונות. המחלקה שלכם צריכה לכלול:- חברים פרטיים:
host(מחרוזת),port(int),timeout(int בשניות) ו-secure(bool) - בנאי ראשי שמקבל את כל ארבעת הפרמטרים ומאתחל את כל החברים באמצעות רשימת אתחול. הבנאי הזה צריך להדפיס
"Connection configured: <host>:<port>" - בנאי שמקבל רק את
hostואתport, ומאציל לבנאי הראשי עם ערך ברירת מחדל של30עבורtimeoutוערך ברירת מחדל שלfalseעבורsecure - בנאי שמקבל רק את
hostומאציל לבנאי עם שני הפרמטרים, עם ערך ברירת מחדל של80עבורport - בנאי ברירת מחדל שמאציל לבנאי עם פרמטר אחד, עם ערך ברירת מחדל של
"localhost"עבורhost - מתודת
getInfo()שמחזירה מחרוזת בתבנית:"<host>:<port> (timeout: <timeout>s, secure: <yes/no>)"
- חברים פרטיים:
main.cpp: הדגימו את שרשרת ההאצלה באמצעות יצירת חיבורים עם בנאים שונים. קראו מהקלט שם מארח ומספר יציאה (כל אחד בשורה נפרדת), ואז:- צרו
Connectionבאמצעות בנאי ברירת המחדל - צרו
Connectionבאמצעות שם המארח בלבד מתוך הקלט - צרו
Connectionבאמצעות שם המארח ומספר היציאה מתוך הקלט - צרו
Connectionעם שם המארח מהקלט, מספר היציאה מהקלט, ערך timeout של60והגדרה שלtrueעבור secure - הדפיסו את
getInfo()עבור כל חיבור, אחד בכל שורה
- צרו
שרשרת ההאצלה פועלת כך: בנאי ברירת המחדל קורא לבנאי עם פרמטר אחד, שקורא לבנאי עם שני פרמטרים, שקורא לבנאי הראשי עם ארבעת הפרמטרים. פירוש הדבר שההודעה "Connection configured" מודפסת פעם אחת עבור כל אובייקט שנוצר, תמיד מתוך הבנאי הראשי.
עבור מצב האבטחה ב-getInfo(), הדפיסו "yes" אם secure הוא true, ואחרת הדפיסו "no".
כללו את קובץ הכותרת שלכם ב-main.cpp באמצעות #include "Connection.h".
נסו בעצמכם
#include <iostream>
#include <string>
#include "Connection.h"
using namespace std;
int main() {
// קרא את הקלט
string host;
int port;
cin >> host;
cin >> port;
// TODO: צור Connection באמצעות בנאי ברירת המחדל
// TODO: צור Connection באמצעות host בלבד מהקלט
// TODO: צור Connection באמצעות host ו-port מהקלט
// TODO: צור Connection עם host ו-port מהקלט, timeout=60, secure=true
// TODO: הדפס את getInfo() עבור כל חיבור, אחד בכל שורה
return 0;
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות OOP
קבצים חיצונייםבנייה וקומפילציה של C++קובצי Header וקובצי מקורמרחבי שמות והיקףמבוא ל-OOP ב-C++מחלקות לעומת אובייקטיםמצביע thisמתודות (פונקציות איבר)תכונות (חברי נתונים)יסודות הבנאים וההורסיםסיכום – מחשבון פשוט4מאפייני מחלקה
חברי מופע לעומת חברים סטטייםגטרים וסטריםפונקציות איבר קבועותמילת המפתח mutableמתודות ומשתנים סטטייםפונקציות ומחלקות ידידותסיכום – מנהל חשבונות בנק7ירושה
ירושה בסיסיתרמות גישה בירושהסדר הקריאות לבנאי ולמפרקדריסת מתודותפונקציות וירטואליות ו־VTableירושה מרובהירושה וירטואליתסיכום – היררכיית עובדים2ניהול זיכרון
זיכרון Stack לעומת Heapמצביעים והפניותזיכרון דינמי (new/delete)מצביעים חכמים ב-C++RAII ב-C++סיכום – מנהל מערכים דינמיים5כימוס
מצייני גישה ב-C++מצייני גישה לעומקהסתרת מידעמבנה לעומת מחלקהמחלקות מקוננות ופנימיותסיכום – מערכת רשומות תלמידים8רב־צורתיות
רב־צורתיות בזמן קומפילציה לעומת בזמן ריצההעמסת פונקציותפונקציות וירטואליות — מבט נוסףפונקציות וירטואליות טהורותמחלקות מופשטותתכנון ממשקים ב־C++המרה דינמית ו־RTTIסיכום — מחשבון צורות3בנאים והורסים
בנאי ברירת מחדלבנאי עם פרמטריםבנאי העתקהבנאי העברהרשימות אתחול בבנאיםבנאים מאציליםמעמיקים בנושא הורסיםכלל השלושה / החמישה / האפססיכום – מחלקת String6העמסת אופרטורים
מבוא להעמסת אופרטוריםהעמסת אופרטורים אריתמטייםהעמסת אופרטורי השוואהאופרטורי זרםהעמסת אופרטור השמההעמסת האופרטורים [] ו־()אופרטורים להמרת טיפוסיםסיכום – מחלקת Matrix9תבניות
תבניות פונקציהתבניות מחלקההתמחות תבניותתבניות ארגומנטים משתנותיסודות SFINAE ותכונות טיפוסיםסיכום – מכל גנריתרגלו בעצמכם: קומפיילר C++ אונליין