מבנה לעומת מחלקה
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C++ של Coddy. שיעור 37 מתוך 104.
ב-C++, struct ו-class כמעט זהים. לשניהם יכולים להיות משתני חבר, פונקציות חבר, בנאים, והם תומכים בירושה. ההבדל היחיד הוא רמת הגישה כברירת מחדל.
ב־class, החברים הם פרטיים כברירת מחדל. ב־struct, החברים הם ציבוריים כברירת מחדל:
struct Point {
int x; // public כברירת מחדל
int y; // public כברירת מחדל
};
class Circle {
double radius; // private כברירת מחדל
public:
double getRadius() { return radius; }
};הדבר נכון גם לגבי ירושה. כברירת מחדל, struct יורש באופן ציבורי, ואילו class יורש באופן פרטי:
struct DerivedStruct : Base {}; // ירושה ציבורית
class DerivedClass : Base {}; // ירושה פרטיתמעבר לברירות המחדל האלה, אין הבדל טכני. עם זאת, למוסכמות יש חשיבות.
רוב מתכנתי C++ משתמשים ב-struct למכלי נתונים פשוטים עם איברים ציבוריים (כמו קואורדינטה או תצורה), וב-class כאשר כימוס והתנהגות חשובים. היצמדות למוסכמה זו מבהירה למפתחים אחרים את כוונת הקוד שלך.
אתגר
קלבוא נבנה מערכת תצורה פשוטה שמדגימה מתי להשתמש ב-struct לעומת class, בהתאם למוסכמות של C++. תיצור struct עבור נתונים פשוטים שאמורים להיות נגישים לכולם, ו-class עבור נתונים שדורשים כימוס וגישה מבוקרת.
תיצור שני קבצים כדי לארגן את הקוד שלך:
Config.h: הגדר גם struct וגם class שמייצגים סוגים שונים של נתוני תצורה.ראשית, צור
structבשםDimensions: מכל נתונים פשוט עבור רוחב וגובה (שניהםint). מכיוון שלחברי struct יש גישה ציבורית כברירת מחדל, אפשר לגשת אליהם ישירות ללא getters. כלול מתודהarea()שמחזירה את המכפלה של הרוחב והגובה.לאחר מכן, צור
classבשםAppConfigשמנהל את הגדרות היישום באמצעות כימוס מתאים. עליו לאחסן את שם היישום (מחרוזת) ואובייקטDimensionsעבור גודל החלון. מכיוון שלחברי class יש גישה פרטית כברירת מחדל, תצטרך להגדיר במפורש את הממשק הציבורי שלו. ספק:- בנאי שמקבל את שם היישום, הרוחב והגובה
- getter בשם
getAppName()שמחזיר את השם - getter בשם
getWindowSize()שמחזיר אתDimensions - מתודה
displayConfig()שמדפיסה:"App: <name>, Window: <width>x<height>, Area: <area>"
main.cpp: הדגם את ההבדל בין שימוש ב-struct לבין שימוש ב-class. קרא שם יישום, רוחב וגובה מהקלט (שלוש שורות נפרדות), ואז:- צור struct מסוג
Dimensionsישירות עם ערכי הרוחב והגובה: גש לחברים שלו ישירות כדי להדפיס:"Direct struct access: <width> x <height>" - צור אובייקט
AppConfigעם שלושת הערכים - קרא ל-
displayConfig()כדי להציג את התצורה המלאה - השתמש ב-getter כדי לקבל את ממדי החלון ולהדפיס:
"Via getter - Area: <area>"
- צור struct מסוג
האתגר הזה מדגיש את המוסכמה: השתמש ב-struct כשיש לך נתונים פשוטים ושקופים (כמו קואורדינטות או ממדים), והשתמש ב-class כשרוצים לשלוט בגישה ולהוסיף התנהגות סביב הנתונים.
המר את קלטי הרוחב והגובה ממחרוזות למספרים שלמים באמצעות std::stoi(). אל תשכח שומרי כותרת בקובץ הכותרת.
נסו בעצמכם
#include <iostream>
#include <string>
#include "Config.h"
using namespace std;
int main() {
// קרא את הקלט
string appName;
string widthStr;
string heightStr;
getline(cin, appName);
getline(cin, widthStr);
getline(cin, heightStr);
int width = stoi(widthStr);
int height = stoi(heightStr);
// TODO: צור struct מסוג Dimensions עם width ו-height
// גש ישירות לשדות שלו כדי להדפיס: "Direct struct access: <width> x <height>"
// TODO: צור אובייקט מסוג AppConfig עם appName, width ו-height
// TODO: קרא ל-displayConfig() על אובייקט ה-AppConfig
// TODO: השתמש בפונקציית הגישה getWindowSize() כדי לקבל את הממדים ולהדפיס: "Via getter - Area: <area>"
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++ אונליין