מצייני גישה ב-C++
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C++ של Coddy. שיעור 34 מתוך 104.
C++ מספקת שלושה מצייני גישה שקובעים מי יכול לגשת לחברי המחלקה: public, protected ו־private. אלה מהווים את הבסיס לכימוס.
class Account {
public:
std::string ownerName; // נגיש מכל מקום
protected:
double interestRate; // נגיש במחלקה זו ובמחלקות הנגזרות ממנה
private:
double balance; // נגיש רק בתוך מחלקה זו
};ניתן לגשת לחברים Public מכל מקום — בתוך המחלקה, ממחלקות נגזרות ומקוד חיצוני. חברים Private הם המגבילים ביותר, וניתן לגשת אליהם רק מתוך המחלקה עצמה. Protected נמצא באמצע — הוא מתנהג כמו private כלפי העולם החיצוני, אך מחלקות נגזרות יכולות לגשת לחברים האלה.
class Account {
private:
double balance;
public:
Account() : balance(0) {}
void deposit(double amount) {
balance += amount; // OK - בתוך המחלקה
}
};
int main() {
Account acc;
acc.deposit(100); // OK - deposit היא פומבית
// acc.balance = 500; // ERROR - balance הוא פרטי
}כברירת מחדל, כל החברים במחלקה הם פרטיים אם לא מציינים מציין גישה. כך מעודדים אותך להחליט במפורש מה צריך להיות חשוף. הנוהג המקובל הוא להגדיר את חברי הנתונים כפרטיים ולספק שיטות ציבוריות כדי ליצור איתם אינטראקציה בטוחה.
אתגר
קלבואו נבנה מערכת פשוטה לניהול עובדים שמדגימה כיצד מצייני גישה קובעים מי יכול לגשת למה. תיצרו מחלקה שבה חלק מהנתונים פרטיים לחלוטין, חלק נגישים למחלקות נגזרות אפשריות, וחלק פתוחים לכולם.
תיצרו שני קבצים כדי לארגן את הקוד:
Employee.h: הגדירו מחלקה בשםEmployeeשמשתמשת בכל שלושת מצייני הגישה כדי להגן על הנתונים בצורה מתאימה:- Public: ה-
nameשל העובד (מחרוזת). אפשר לגשת אליו מכל מקום - Protected: ה-
departmentשל העובד (מחרוזת): נגיש בתוך המחלקה ובמחלקות נגזרות, אך לא מחוץ לה - Private: ה-
salaryשל העובד (double): נגיש רק בתוך המחלקה עצמה - בנאי שמקבל שם, מחלקה ושכר כדי לאתחל את כל שלושת החברים
- מתודה ציבורית
getSalary()שמחזירה את ערך השכר הפרטי - מתודה ציבורית
getDepartment()שמחזירה את ערך המחלקה המוגן - מתודה ציבורית
giveRaise(double amount)שמגדילה את השכר בסכום הנתון (רק אם הסכום חיובי) - מתודה ציבורית
displayInfo()שמדפיסה את פרטי העובד בתבנית:"Name: <name>, Department: <department>, Salary: $<salary>"
- Public: ה-
main.cpp: הדגימו כיצד מצייני גישה פועלים באמצעות אינטראקציה עם אובייקטEmployee. קראו מהקלט את שם העובד, המחלקה שלו והשכר שלו (שלוש שורות נפרדות), ואז:- צרו אובייקט
Employeeעם ערכי הקלט - הדפיסו את שם העובד באמצעות גישה ישירה לחבר הציבורי:
"Direct access - Name: <name>" - הדפיסו את המחלקה באמצעות פונקציית הגישה:
"Via getter - Department: <department>" - הדפיסו את השכר באמצעות פונקציית הגישה:
"Via getter - Salary: $<salary>" - תנו לעובד העלאה של
5000.0 - הדפיסו
"After raise:" - קראו ל-
displayInfo()כדי להציג את הפרטים המעודכנים
- צרו אובייקט
עצבו את כל ערכי השכר עם שתי ספרות אחרי הנקודה העשרונית באמצעות std::fixed ו-std::setprecision(2) מתוך <iomanip>. המירו את קלט השכר ממחרוזת ל-double באמצעות std::stod().
התובנה המרכזית כאן היא שאפשר לגשת ישירות ל-name מתוך main, אך אי אפשר לגשת ישירות ל-department או ל-salary. יש להשתמש בפונקציות הגישה הציבוריות. זו פעולה של כימוס: המחלקה קובעת כיצד אפשר לגשת לנתונים שלה ולשנות אותם.
נסו בעצמכם
#include <iostream>
#include <string>
#include <iomanip>
#include "Employee.h"
using namespace std;
int main() {
// קרא את הקלט
string name;
string department;
string salaryStr;
getline(cin, name);
getline(cin, department);
getline(cin, salaryStr);
double salary = stod(salaryStr);
// הגדר את הדיוק להצגת השכר
cout << fixed << setprecision(2);
// TODO: צור אובייקט Employee עם ערכי הקלט
// TODO: הדפס את שם העובד באמצעות גישה ישירה לשדה הציבורי
// פורמט: "Direct access - Name: <name>"
// TODO: הדפס את המחלקה באמצעות מתודת ה-getter
// פורמט: "Via getter - Department: <department>"
// TODO: הדפס את השכר באמצעות מתודת ה-getter
// פורמט: "Via getter - Salary: $<salary>"
// TODO: הענק לעובד העלאה של 5000.0
// TODO: הדפס "After raise:"
// TODO: קרא ל-displayInfo() כדי להציג את המידע המעודכן
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++ אונליין