49
ססססס סס'7 - לללל לC ++ ללללל לללללל ללללללל namespaces לללללל- לC ++

תרגול מס ' 7

  • Upload
    effie

  • View
    82

  • Download
    2

Embed Size (px)

DESCRIPTION

תרגול מס ' 7. מבוא ל- C++ הקצאת זיכרון דינאמית namespaces const משתנים מיוחסים קלט/פלט ב- C++ מחלקות. מבוא ל- C++. C++. C++ היא שפת תכנות שנבנתה מעל C C++ מוסיפה מגוון רב של תכונות מתקדמות בעיקר עבור תכנות מונחה עצמים השלד הבסיסי של הקוד בשפה זהה ל- C - PowerPoint PPT Presentation

Citation preview

Page 1: תרגול מס ' 7

7תרגול מס' -מבוא לC++הקצאת זיכרון דינאמיתnamespacesconst

משתנים מיוחסים-קלט/פלט בC++מחלקות

Page 2: תרגול מס ' 7

2מבוא לתכנות מערכות - 234122

++Cמבוא ל-

Page 3: תרגול מס ' 7

3מבוא לתכנות מערכות - 234122

C++

C++ היא שפת תכנות שנבנתה מעלCC מגוון רב של תכונות מתקדמות++ מוסיפה

בעיקר עבור תכנות מונחה עצמים–

-השלד הבסיסי של הקוד בשפה זהה לC רוב הקוד שלC-ניתן לקמפול ישירות כ C++-נהוג בCיתרונות השפה++ לבצע דברים אחרת תוך שימוש ב

!Cקוד בסגנון ++ Cלא כותבים ב-–יש תחליפים ++ - Cועוד ב-* printf, FILE*, voidלא נהוג להשתמש ב-–

עדיפים

#include <iostream>using namespace std; int main(int argc, char** argv) {

cout << "Hello world" << endl;

return 0;}

Page 4: תרגול מס ' 7

4מבוא לתכנות מערכות - 234122

C++++ כדי לקמפל קודC נשתמש בקומפיילר g++

++.g הוא gcc, למעשה gccאופן השימוש זהה ל-–

-קבצי הheader++ הסטנדרטיים של C למשל ללא סיומת הם ,iostreamC כמו ב-hקבצים הנכתבים על ידי משתמשים הם בעלי סיומת –

-קבצי הsource-ב C הם בעלי סיומת ++cpp, cc או C)גדולה( כדי לכלול קבציheader של C מוסיפים c:בתחילת שמם, למשל

#include <cstdio>

C99-ו C11 הם סטנדרטים חדשים של C-אשר מוסיפים תכונות פופולריות מ C:++(if או משפט forאתחול משתנים באמצע בלוק )ובתוך לולאת –

constערכים קבועים - –שימוש בהערות של שורה אחת //–

-כל התכונות האלה קיימות בCובדרך כלל חשיבותן גבוהה לסגנון השפה ++

Page 5: תרגול מס ' 7

5מבוא לתכנות מערכות - 234122

הקצאת זיכרון דינאמית

newdelete

Page 6: תרגול מס ' 7

6מבוא לתכנות מערכות - 234122

הקצאת זיכרון דינאמית++-הקצאות זיכרון דינאמיות בC מתבצעות בעזרת האופרטורים new -וdelete ניתן להקצות משתנה חדש )ולאתחלו( על ידיnew:

int* ptr = new int; // No explicit initialization

int* ptr = new int(7); // The new integer is initialized to 7

ניתן להקצות מערך של משתנים על ידיnew[size_t]:int* array = new int[n];

שחרור של עצם שהוקצה על ידיnew מתבצע בעזרת delete:delete ptr;

שחרור של עצם שהוקצה על ידיnew[size_t] מתבצע בעזרת delete][:delete[] array;

Page 7: תרגול מס ' 7

7מבוא לתכנות מערכות - 234122

new-ו deleteדוגמאות -

בין להתבלבל אסור delete-ו delete][ את אסור לערבבnew-ו delete עם malloc-ו free

free ולשחרר עם newלמשל להקצות עם –

את ערך המצביע המוחזר מ-אין צורך לבדוקnew–new אינה מחזירה NULL(10 מתבצע בעזרת מנגנון החריגות )תרגול Cטיפול בשגיאות ב-++–

int* ptr = malloc(sizeof(int));if (!ptr) {

// handle errors ...}*ptr = 5;int* array = malloc(sizeof(*array)* *ptr);if (!array) {

// handle errors ...}

free(ptr);free(array);

int* ptr = new int(5);int* array = new int[*ptr];// No need to check for NULLs

delete ptr;delete[] array;

C++ C

Page 8: תרגול מס ' 7

8מבוא לתכנות מערכות - 234122

הקצאת זיכרון דינאמית - סיכום

-בC-משתמשים ב ++new-ו new[size_t]כדי להקצות זיכרון חדש האופטורnewמחזיר מצביע מהטיפוס המתאים -אין צורך לבדוק את הצלחת ההקצאה כמו בC-בC-משתמשים ב ++delete-ו deleteכדי לשחרר זיכרון ][new משחררים עם delete-ו new[size_t] עם delete][-לא משתמשים בmalloc-ו free מלבד המקרה של חיבור קוד( C)ישן

Page 9: תרגול מס ' 7

9מבוא לתכנות מערכות - 234122

Namespaces

Page 10: תרגול מס ' 7

10מבוא לתכנות מערכות - 234122

namespace-בC ניתן לאגד מספר פונקציות וטיפוסים בצורה לוגית תחת ++namespace

בדומה לארגון קבצים בתיקיות–

namespace math {

double power(double base, double exp);

double sqrt(double number);

double log(double number);

}

-לכל פונקציה )או טיפוס או משתנה( המוגדרת בnamespace מהצורהשם מלא יש

<namespace>::<item>

:: קרוי אופרטור(scope משמש להפרדה בין שמות )namespace כאשר מציינים שמות מלאים

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

double root = math::sqrt(10.0);

Page 11: תרגול מס ' 7

11מבוא לתכנות מערכות - 234122

namespace ניתן להשתמש בהוראתusing כדי לחסוך את כתיבת השם המלא בכל פעם

הנוכחיnamespace "תעתיק" את הגדרת הפונקציה ל-usingהוראת –

using math::power;

ניתן להשתמש בהוראותusing namespace <name > כדי לבצעusingלכל תוכן בבת אחתnamespaceה-

using namespace math;

ניתן לקנןnamespace:אחד בתוך השני namespace mtm {

namespace ex4 {

int f(int n);

}

}

-כל ההגדרות מהספריה הסטנדרטית מופיעות תחת הnamespace הסטנדרטי הקרוי stdאלא להשתמש רק בחלקים מהספריה הסטנדרטית הדרושים using namespace stdמומלץ לא לבצע –

-הnamespace הראשי מצוין על ידי :: מה ההבדל ביןf-ל ::f?

Page 12: תרגול מס ' 7

12מבוא לתכנות מערכות - 234122

namespaceיתרונות:

ניתן לקבץ בצורה לוגית נוחה פונקציות דומות–

ללא חשש להתנגשויותשמות קצרים וברורים יותר ניתן להשתמש ב–

מאפשר החלפה, מימוש ומיזוג של מימושים שונים בקלות–

typedef enum { MTM_OUT_OF_MEMORY, /*...*/ } MtmErrorCode;

void mtmPrintErrorMessage(MtmErrorCode error);

namespace mtm {enum ErrorCode { OUT_OF_MEMORY, /*...*/ };

 void printErrorMessage(ErrorCode error);

}

C++

C

Page 13: תרגול מס ' 7

13מבוא לתכנות מערכות - 234122

namespaceסיכום -

-ניתן לקבץ קוד בצורה לוגית בעזרת חלוקתו לnamespaceשונים -ניתן להשתמש בusingכדי להימנע מכתיבת שמות מלאים בקוד בזכותnamespace ניתן לשמור על שמות קצרים וברורים ללא צורך

Cבתחיליות כמו ב-:: הקוד מהספריה הסטנדרטית מופיע תחתstd

Page 14: תרגול מס ' 7

14מבוא לתכנות מערכות - 234122

קבועים

הגדרת משתנים קבועיםמצביעים קבועים

Page 15: תרגול מס ' 7

15מבוא לתכנות מערכות - 234122

constקבועים - בהכרזה על משתנה ניתן להוסיף לשם הטיפוס את המילה השמורהconst של משתנה אשר מוגדר כ-לא ניתן לשנות את ערכוconst קבוע( לאחר אתחולו(

לכן חובה לאתחל משתנים קבועים–

const int n = 5;

n = 7; // error: assignment of read-only variable `n'

const int m; // error: uninitialized const `m'

של פונקציה כ-פרמטרים וערכי חזרה ניתן להכריז עלconst:char* strcpy(char* destination, const char* source);

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

const char* studentGetName(Student s);

ניתן להחזיר משתנה פרטי ללא חשש לגרימת נזק מצד המשתמש–

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

Page 16: תרגול מס ' 7

16מבוא לתכנות מערכות - 234122

constקבועים - כאשר מוסיפיםconst:להגדרת מצביע ייתכנו מספר אפשרויות

הנשמרת במצביע קבועה הכתובת–

הנשמר במשתנה המוצבע קבועהערך–

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

הוא מתייחס לשם הטיפוס הבא אחריוראשון מופיע constאם ה-–const int* cptr;

מתייחס לשמאלו constבכל שאר המקרים –int const* cptr2;

int* const ptr = NULL; // Must be initialized, why?

אחדconstיותר מ-ניתן לרשום –const int* const ptr = NULL;

Page 17: תרגול מס ' 7

17מבוא לתכנות מערכות - 234122

קבועים - דוגמאות?אילו מהשורות הבאות יגרמו לשגיאת קומפילציה

1) int i = 7;

2) const int ci = 17;

3) const int* pci = &ci;

4) *pci = 7;

5) pci = &i;

6) int* pi = &ci;

7) pci = pi;

8) pi = pci;

9) int* const cpi = &i;

10) *cpi = 17;

11) cpi = &i;

12) int* const cpi2 = &ci;

13) const int* const ccpi = &ci;

14) ccpi = &ci;

Page 18: תרגול מס ' 7

18מבוא לתכנות מערכות - 234122

:משתנה אשר קבוע בהקשר אחד אינו בהכרח קבוע

-בC מגדירים קבועים בעזרת משתנים קבועים )גלובליים אם צריך( במקום בעזרת ++#defineמאפשר את בדיקת הטיפוס על יד הקומפיילר–

מאפשר הגדרת קבועים מטיפוסים מורכבים–const int MAX_SIZE = 100;

const Rational ZERO = rationalCreate(0,1);

static const char* const MONTHS[] = {"JAN","FEB","MAR","APR","MAY","JUN",

"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};

( חשוב להקפיד על שימוש נכון בקבועיםconst correctness-כאשר ניתן ב )C++כדור שלג של שינויים יוצרת const מההתחלה, הוספה מאוחרת של constהקפידו על –

void h() {X val; // val can be modifiedg(&val);

}

קבועים - הערות נוספות

void g(const X* p) {// can't modify *p

here}

Page 19: תרגול מס ' 7

19מבוא לתכנות מערכות - 234122

constסיכום -

-ניתן להגדיר משתנים בCכקבועים כך שלא ניתן לשנות את ערכם ++ניתן להגדיר פרמטרים וערכי חזרה של פונקציות כקבועים עבור מצביעים ניתן להגדיר את הערך המוצבע כקבוע ואת ערך המצביע

כקבוע-יש להשתמש בconstכאשר ניתן כדי למנוע באגים -הגדרת קבועים בCמתבצעת בעזרת משתנים קבועים ++

Page 20: תרגול מס ' 7

20מבוא לתכנות מערכות - 234122

משתנים מיוחסים

משתנים מיוחסיםמשתנים מיוחסים קבועים

Page 21: תרגול מס ' 7

21מבוא לתכנות מערכות - 234122

Referenceמשתנים מיוחסים - משתנה מיוחס(referenceהוא שם נוסף לעצם קיים ) עבור שם טיפוסX, X& רפרנס ל- הואX

int n = 1;

int& r = n; // r and n now refer to the same int

r = 2; // n = 2

חובה לאתחל רפרנסהעצם אליו מתייחס הרפרנס נקבע בהכרזה, לכןint& r; // error: initializer missing

אתחול הרפרנס שונה מהשמה אליוr = n; // a normal assignment between two ints

לאחר אתחול הרפרנס לא ניתן להפעיל פעולות "על הרפרנס" אלא רק על העצםאליו הוא מתייחס

int nn = 0;

int& rr = nn;

rr++; // nn is incremented to 1

את העצם אליו מתייחסים לאחר האתחוללא ניתן לשנות

Page 22: תרגול מס ' 7

22מבוא לתכנות מערכות - 234122

Referenceמשתנים מיוחסים - אתחול של רפרנס יכול להתבצע רק על ידיlvalue

int& x = 1; // error: invalid initialization from temporary value

int& y = a+b; // same thing

עבור טיפוסX - ניתן להגדיר רפרנס לקבוע const X&ניתן לאתחל רפרנס לקבוע גם על ידי ערכים זמניים–

const int& cx = 1;

const int& cy = a+b;

( של פונקציה יכולים להיות רפרנסוערכי חזרה )פרמטריםהרפרנס יאותחל כך שיתייחס לעצם המועבר לפונקציה )מוחזר מהפונקציה(–

void swap(int& a, int& b) {

int temp = a;

a = b;

b = temp;

}

Page 23: תרגול מס ' 7

23מבוא לתכנות מערכות - 234122

Referenceמשתנים מיוחסים - :הפונקציה הבאה מחזירה את האיבר המקסימלי במערך כרפרנס

int& getMax(int* array, int size) {

int max = 0;

for (int i = 0; i < size; ++i) {

if (array[i] > array[max]) {

max = i;

}

}

return array[max];

}

רפרנס הואlvalue בעצמו, לכן ניתן למשל לרשום קוד מהצורה הבאהint array[5] = { 1, 2, 3, 4, 5 };

getMax(array,5) = 0 ; // array[4] = 0

אסור להחזיר רפרנס למשתנה מקומי?max כך שתחזיר את getMaxמה יקרה אם נשנה את –

אמנם הקוד הזה נראה מוזר, אך בהמשך נראה שימושים טבעיים עבור

החזרת רפרנסים

Page 24: תרגול מס ' 7

24מבוא לתכנות מערכות - 234122

Referenceמשתנים מיוחסים - קיים דמיון רב ביןX &-לX* const:עם זאת קיימים גם הבדלים חשובים ,

בעוד משתנה מיוחס תמיד מתייחס לעצם חוקי NULLמצביע יכול להצביע ל-–

עבור מצביעים יש צורך להשתמש ב-* ו-& כדי לבצע פעולות–

ניתן להשתמש בחשבון מצביעים כדי להסתכל על הזיכרון "ליד" המצביע–

לשלוח פרמטרים כ-מומלץconst X&כל עוד זה מתאים וכו'...( אין הבדל ולכן אפשר להעביר int, float)משתנים פרימיטיביים עבור –

by value)יותר קצר וקריא(

Page 25: תרגול מס ' 7

25מבוא לתכנות מערכות - 234122

משתנים מיוחסים - סיכום

עבור טיפוסX הטיפוס ,Xמאפשר נתינת שם חדש לעצם & לאחר האתחול שלXלא ניתן לשנות את העצם אליו הוא מתייחס &const X( יכול להתייחס לערכים זמניים &X)לא יכול &ניתן להעביר פרמטרים ולהחזיר ערכים מפונקציות כרפרנסיםאסור להחזיר רפרנס למשתנה מקומי-מומלץ להעביר פרמטרים שאינם פרימיטיביים לפונקציות כconst X&

Page 26: תרגול מס ' 7

26מבוא לתכנות מערכות - 234122

העמסת פונקציות

העמסת פונקציותבחירת פונקציה מתאימהערכי ברירת מחדל

Page 27: תרגול מס ' 7

27מבוא לתכנות מערכות - 234122

Functionהעמסת פונקציות - Overloading

-בC מספר וסוג הפרמטרים וגם על ידי שמה++ פונקציה מזוהה על ידישלה בה פונקציה מזוהה על ידי שמה בלבדCבניגוד ל-–

מבחינתC הפונקציות ++void print(int) -וvoid print(double)

שונות-ניתן בC על ו"להעמיס" ++ לכתוב מספר פונקציות בעלות אותו שם

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

להvoid print_int(int);void print_double(double);void print_string(const char*);// ...print_int(5);print_double(3.14);print_string("Hello");

void print(int);void print(double);void print(const char*);// ...print(5); // print(int) called print(3.14); // print(double) called print("Hello"); // print(const char*)

C++ C

Page 28: תרגול מס ' 7

28מבוא לתכנות מערכות - 234122

העמסת פונקציות - בחירת הפונקציה

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

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

, מערך למצביע(⇐T const Tאו המרות טריוויאליות ) מדויקת התאמה1.

⇐bool int, char int, float double )קידוםהתאמה בעזרת 2. ⇐ וכו'...(⇐

⇐int double, double int, T* void)המרות מובנות התאמה בעזרת 3. ⇐ ⇐*

)תרגול הבא(המרות שהוגדרו על ידי המשתמש התאמה בעזרת 4.

(printf( )למשל ...ellipsisהתאמה לפונקציה עם מספר ארגומנטים משתנה )5.

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

אם קיימות שתי התאמות ברמה הגבוהה ביותר בה נמצאו התאמות אז הקריאה מכילה והיא לא תתקמפלדו-משמעות

לא ניתן לכתוב שתי פונקציות השונות אינה תלויה בערך ההחזרהבחירת הפונקציה ,רק בערך ההחזרה שלהן

Page 29: תרגול מס ' 7

29מבוא לתכנות מערכות - 234122

העמסת פונקציות - דוגמאות

?אילו מהפונקציות הבאות תיקרא בכל אחת מהקריאותvoid print(int);void print(double);void print(const char*);void print(char); void h(char c, int i, float f, double d, long l) {

print(c);print(f);print(d);print(i);print(l);

 print('a');print(49);print(0);print("Hello");

}

במקרה של דו-משמעות יש להוסיף המרות מפורשות כדי להבהיר לקומפיילר באיזו פונקציה

לבחור, למשל:print(int(l));print(double(l));

העמסות יכולות לסבך את הקוד, השתמשו בהן רק אם קורא הקוד יוכל להבין בקלות מה קורה מהסתכלות על

הקריאה לפונקציה

Page 30: תרגול מס ' 7

30מבוא לתכנות מערכות - 234122

ערכי ברירת מחדל

קיימות פונקציות אשר אחד הארגומנטים שלהן הוא ברוב המקרים אותו ערךvoid print(int n, int base);

print(6, 10);

print(5, 10);

print(5, 8); // Print in octal

print(17,10);

print(14,2); // binary

:נוכל לנצל את מנגנון העמסת הפונקציות כדי לפתור בעיה זוvoid print(int n) { print(n, 10); }

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

void print(int n, int base = 10);

Page 31: תרגול מס ' 7

31מבוא לתכנות מערכות - 234122

ערכי ברירת מחדל

:ניתן לתת ערך ברירת מחדל רק לפרמטרים האחרונים של הפונקציה

int f(int n, int m = 0, char* str = 0); // ok

int g(int n = 0, int m = 0, char* str); // error

int h(int n = 0, int m , char* str = NULL); // error

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

int f(int n = 8);

//...

int f(int n) { // writing n = 8 again (or any other value) is an error

return n;

}

Page 32: תרגול מס ' 7

32מבוא לתכנות מערכות - 234122

העמסת פונקציות - סיכום

-בCפונקציה מזוהה לפי שמה והפרמטרים אותם היא מקבלת ++ הקומפיילר אחראי לבחירת הפונקציה המתאימה מבין כל הפונקצוית

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

קורא הקוד

Page 33: תרגול מס ' 7

33מבוא לתכנות מערכות - 234122

++Cקלט/פלט ב-

<<-האופרטורים << ו-הערוצים הסטנדרטיים בC++

Page 34: תרגול מס ' 7

34מבוא לתכנות מערכות - 234122

++Cקלט/פלט ב--ערוצי הקלט ופלט הסטנדרטיים מיוצגים בC על ידי המשתנים הגלובליים הבאים ++

(:iostream)מוגדרים בקובץ –coutערוץ הפלט הסטנדרטי :

–:cin ערוץ הקלט הסטנדרטי

–cerrערוץ השגיאות הסטנדרטי :

אופרטור <<כדי להדפיס משתנה כלשהו לערוץ פלט משתמשים בendl לחוצץ על ידי הדפסת flushניתן להדפיס ירידת שורה ולבצע –

אופרטור >>כדי לקלוט ערך למשתנה מערוץ קלט משתמשים ב מספר הדפסות/קריאות בבת אחתלשרשרניתן

int main() {

int n;

std::cin >> n; // Reads an int from user

std::cout << "You entered " << n << std::endl;

return 0;

}

Page 35: תרגול מס ' 7

35מבוא לתכנות מערכות - 234122

++Cקלט/פלט ב-:יתרונות

כדי להדפיסקודים מוזרים לא צריך לזכור –

המודפסלהתבלבל בסוג הטיפוס לא ניתן –

עבור טיפוסים שיצרנו )בתרגול הבא(את השימוש בקלט/פלטניתן להרחיב –#include <stdio.h> 

int main() {int n;const char* str = "Hello";int* ptr = &n;fscanf(stdin, "%d", &n);fprintf(stdout, "%s\n", str);fprintf(stderr, "%d at %x\n",

n, ptr);return 0;  

}

#include <iostream>using std::cout;using std::cerr;using std::cin;using std::endl; int main() {

int n;const char* str = "Hello";int* ptr = &n;cin >> n;cout << str << endl;cerr << n << " at "<< ptr

<< endl;return 0;  

}

C++ C

Page 36: תרגול מס ' 7

36מבוא לתכנות מערכות - 234122

++ - סיכוםCקלט/פלט ב-

-הערוצים הסטנדרטיים מיוצגים בC על ידי המשתנים ++cout, cin-ו cerr>> מדפיסים לערוצי פלט בעזרת אופרטור<< קולטים ערכים מערוצי קלט בעזרתההדפסה או הקריאה נקבעים לפי סוג הטיפוס)ניתן להרחיב את שיטה זו עבור טיפוסים שיצרנו בעצמנו )תרגול הבא

Page 37: תרגול מס ' 7

37מבוא לתכנות מערכות - 234122

Classesמחלקות -

מתודותthispublic-ו privateבנאים והורסים

משתנים ופונקציותסטטיות

מחלקותמחלקת מחסנית

Page 38: תרגול מס ' 7

38מבוא לתכנות מערכות - 234122

++Cטיפוסי נתונים ב- יצירת טיפוסי נתונים הוטמעה בשפתC++

-בC ניתן להגדיר את הפונקציות עבור ++ישירות בתוך המבנהטיפוס הנתונים

פונקציות המוגדרות כחלק מהמבנה נקראות( אוmethods )מתודות

(member functions)פונקציות חברות

כדי להפעיל מתודה יש צורך בעצם מהטיפוסהמתאים להפעיל אותה עליו

לכל מתודה יש פרמטר נסתר בשםthis והואמצביע לעצם עליו היא הופעלה

struct Point {

int x, y;

double distance(const Point& p) {

int dx = this->x - p.x;

int dy = this->y - p.y;

return sqrt(dx*dx+dy*dy);

}

};

 

int main() {

Point p = { 3, 4 };

Point p2 = { 2, 8 };

double d = p.distance(p2);

return 0;

}

Page 39: תרגול מס ' 7

39מבוא לתכנות מערכות - 234122

Methodsמתודות - מתודות ניתן לממש ישירות בתוך

המבנה )כמו בשקף הקודם( או להכריז עליהן במבנה ולממשן מחוץ

לו:

ב-הגדרות טיפוסיםC יופיעו ++hבדרך כלל בקבצי

בתוך אם מימוש הפונקציה נעשהh אז הוא יופיע בקובץ ה-המבנה

נשים חיצוניאם מימוש הפונקציה המתאיםcpp/cc/Cאותו בקובץ ה-

struct Point {int x, y;

 double distance(const Point&

p);};

double Point::distance(const Point& p) {

int dx = this->x - p.x;int dy = this->y - p.y;return sqrt(dx*dx+dy*dy);

}

Page 40: תרגול מס ' 7

40מבוא לתכנות מערכות - 234122

thisהמצביע לכל מתודה של עצם מטיפוסX נשלח

thisששמו X* constמצביע מטיפוס

את ה- להשמיט ניתןthis כל עוד אין דו-משמעות

ניתן להגדיר מתודה כך שתפעל עלהוספת על ידי constעצמים שהינם

constבסוף חתימת הפונקציה

עבור מתודה לעצם קבועthis יהיה const X* constמטיפוס

אםthis קבוע עבור מתודה מסוימת שלו קבועיםכל השדות גם

struct Point {int x, y;

 double distance(const Point& p)

const;void set(int x, int y);

}; void Point::set(int x, int y) {

this->x = x;this->y = y;

}

double Point::distance(const Point& p) const {

int dx = x - p.x;int dy = y - p.y;return sqrt(dx*dx+dy*dy);

}

מדוע לא ניתן setלהגדיר את

?constכ-

Page 41: תרגול מס ' 7

41מבוא לתכנות מערכות - 234122

Access Controlבקרת גישה - כדי לשמור על הסתרת המימוש

מהמשתמש ניתן להגדיר חלקים פרטיים וחלקים פומביים

-קוד אשר כתוב בתוך הnamespace של הטיפוס רשאי לגשת לחלקים פרטיים

קוד אשר כתוב מחוץ למבנה אינו יכוללגשת לחלקים אלו

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

למשל, פונקציות עזר של הטיפוס יוגדרו–privateכ-

struct Point {

private:

int x, y;

 

public:

double distance(const Point& p);

void set(int x, int y);

};

// ...

int main() {

Point p;

p.x = 5; // error: 'int Point::x'

// is private

p.set(3, 4);

double d = p.distance(p);

 

return 0;

}

Page 42: תרגול מס ' 7

42מבוא לתכנות מערכות - 234122

Classes מחלקות - -בדרך כלל מגדירים טיפוסים בC עם המילה השמורה ++class

public הוא בברירת המחדל עבור בקרת הגישה - struct ל-classההבדל בין –class עבור private ו-structעבור

-נהוג להשתמש בstruct עבור טיפוסים פשוטים שכל שדותיהם הינם public

 

class Point {int x, y;

 

public:double distance(const Point&

p) const;void set(int x, int y);

};

struct Point {private:

int x, y; public:

double distance(const Point& p) const;

void set(int x, int y);};

Page 43: תרגול מס ' 7

43מבוא לתכנות מערכות - 234122

Constructorsבנאים - לכל מחלקה ניתן להגדיר סוג

מיוחד של מתודות הנקראות C’torאו Constructors )בנאים

בקיצור( ששמן כשם המחלקה

בנאים משמשים לאתחול שלעצם חדש מהמחלקה

class Point {int x, y;

 public:

Point(int x, int y);double distance(const Point&

p) const;}; Point::Point(int x, int y) {

this->x = x;this->y = y;

} int main() {

Point p1(3, 4);const Point p2(2, 8);cout << p1.distance(p2) <<

endl;return 0;

Page 44: תרגול מס ' 7

44מבוא לתכנות מערכות - 234122

Destructorsהורסים - לכל מחלקה ניתן להגדיר סוג נוסף של

( D’torאו Destructor )הורסמתודה הקרויה ~ושמה כשם המחלקה ותחילית

ההורס של המחלקה נקרא אוטומטיתבזמן שחרור עצם של המחלקה

עוד על בנאים והורסים בתרגולים הבאים

class Array {int* data;int size;

public:Array(int size);~Array();// More

methods ...};

Array::Array(int size) {data = new

int[size];this->size = size;

} Array::~Array() {

delete[] data;}

int main() {Array array(50);// code ...return 0;

} // d'tor called

Page 45: תרגול מס ' 7

45מבוא לתכנות מערכות - 234122

פונקציות ושדות סטטיים

משתנים סטטיים ניתן להגדירבמחלקה, משתנים אלו אינם

שייכים לעצם ספציפי מתודות סטטיותניתן להגדיר ,

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

מתודה סטטית רשאית לגשתלחלקים פרטיים של המחלקה

משתנים ומתודות סטטייםמצייתים לחוקי בקרת הגישה

אם למשל נגדיר משתנה סטטי –כפרטי הוא יהיה נגיש רק מתוך

המחלקה

class Point {int x, y;static Point origin;

public:Point(int x, int y);double distanceFromOrigin()

const;static void setOrigin(int x,

int y);};

Point Point::origin(0,0);

double Point::distanceFromOrigin() const {

int dx = x - origin.x;int dy = y - origin.y;return sqrt(dx*dx + dy*dy);

}

void Point::setOrigin(int x, int y) {origin.x = x;origin.y = y;

}

Page 46: תרגול מס ' 7

46מבוא לתכנות מערכות - 234122

מחלקת מחסנית

למחלקה ב-5נמיר כעת את המחסנית שלנו מתרגול C++-בC חריגות++ ערכי שגיאה מטופלים על ידי

( ולכן לא נהוג להחזיר קודי שגיאה10)תרגול -כדי לכתוב קוד גנרי בCמשתמשים בתבניות ++

( ולכן נסתפק במחסנית של מספרים10)תרגול שלמים בינתיים

2

17

3

nextIndex

5

class Stack {int* data;int size;int nextIndex;

 public:

Stack(int size = 100);

~Stack();int getSize()

const;void push(int

n);void pop();int& top();const int& top()

const;};

Page 47: תרגול מס ' 7

47מבוא לתכנות מערכות - 234122

מימוש המחסניתStack::Stack(int size) {

data = new int[size];this->size = size;nextIndex = 0;

} Stack::~Stack() {

delete[] data;} void Stack::push(int n) {

if (nextIndex >= size) {error("Stack

full");}data[nextIndex++] = n;

}

int Stack::getSize() const {return nextIndex;

}

void Stack::pop() {if (nextIndex <= 0) {

error("Stack empty");

}nextIndex--;

}

int& Stack::top() {if (nextIndex <= 0) {

error("Stack empty");

}return data[nextIndex -

1];}

const int& Stack::top() const {if (nextIndex <= 0) {

error("Stack empty");

}return data[nextIndex -

1];}

מה ההבדל?

Page 48: תרגול מס ' 7

48מבוא לתכנות מערכות - 234122

שימוש במחסנית#include "stack.h"#include <stdio.h>

int main() {Stack stack =

stackCreate(100);Stack stack2 =

stackCreate(50);stackPush(stack, 1);stackPush(stack, 213);stackPop(stack);printf("%d\

n",stackTop(stack)); stackDestroy(stack);

stackDestroy(stack2);return 0;

}

#include "stack.h"#include <iostream>using std::cout;using std::endl;

int main() {Stack stack;Stack stack2(50);stack.push(1);stack.push(213);stack.pop();cout << stack.top() <<

endl;

return 0;}

C++ C

Page 49: תרגול מס ' 7

49מבוא לתכנות מערכות - 234122

מחלקות - סיכום

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

הופעלה המתודה כדי למנוע גישה מהמשתמש למימוש ניתן להגדיר חלקים מהמחלקה

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