לדלג לתוכן

C++‎

מתוך ויקיפדיה, האנציקלופדיה החופשית


שגיאות פרמטריות בתבנית:לשכתב

פרמטרי חובה [ נושא ] חסרים

C++‎ היא שפת תכנות המבוססת על שפת התכנות C ומיישמת את עקרונות תכנות מונחה העצמים. כיום שפה זו הינה אחת השפות הפופולריות בקרב מתכנתים בעולם. אף שנעשה ניסיון להציע שפות מודרניות שמבוססות עליה, היא עדיין נותרה דומיננטית, חשובה ורלוונטית לרוב סוגי התכנות הקיימים. על פי נתוני חבר ITR בישראל המתכנתים בה מבוקשים ושכרם ניצב בראש טבלת שכר המתכנתים‏‏[1].

היסטוריה ומקור השם

המדריך הראשון לשפת ++C

השפה פותחה החל משנת 1979 ובתחילת שנות ה־80 על ידי ביארן סטרוסטרופ ממעבדות בל, כאשר הגרסה הראשונה נקראה C with classes (דהיינו "C עם מחלקות"). גרסה זו זכתה לשימוש ב־1983 במעבדות בל. בשנה זו קיבלה השפה את שמה החדש "++C". הגרסה המסחרית הראשונה הופצה בשנת 1985 יחד עם פרסום המדריך הראשון לשפה על ידי סטרוסטרופ, כאשר תמיכה בתבניות הוספה רק מאוחר יותר בגרסה השנייה של מדריך זה. השפה תוקננה על ידי ארגון התקינה הבינלאומי בשנת 1997.

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

מבנה השפה

בשפת C++‎ ממומשים העקרונות הכלליים של התכנות מונחה עצמים: כימוס, הורשה ורב־צורתיות (פולימורפיזם). ההורשה שמאפשרת C++‎ יכולה להיות הורשה מכמה טיפוסי בסיס, דהיינו הורשה מרובה.

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

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

בשפת C ניתן להכריז על משתנה בתחילת בלוק בלבד, ואילו בשפת C++‎ ניתן להכריז על משתנה בכל מקום בבלוק שינוי נוסף הוא האפשרות להתייחס בגוף פונקציה למשתנה גלובלי, ששמו כשם משתנה מקומי שקיים בפונקציה. כמו כן, בגרסאות המאוחרות של השפה הוסף טיפוס עבור ערך בוליאני (ששמו bool), שלא היה קיים בשפת C.

טיפוסיות חזקה (STRONG TYPING)

בשפת C המהדר מבצע המרות טיפוסים בצורה אוטומטית ובקלות יחסית, ואף ניתן להגדיר משתנה או פרמטר מסוג *void שיכול להיות 'כל טיפוס'. בשפת C++‎ הוקשחו הכללים והמרות טיפוסים נעשות רק לפי הגדרות המובנות בשפה או כאלה שהוגדרו על ידי המשתמש. באופן זה ניתן לגלות שגיאות רבות כבר בשלב ההידור. עם זאת עדיין ניתן לכפות המרה באמצעות Casting מכל טיפוס לכל טיפוס ולהשתמש ב-union המכיל שני טיפוסים חסרי קשר.

תכונות פרמטרים של פונקציה

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

  • אפשר להגדיר אותם כקבועים באמצעות המילה השמורה const, וכך אין אפשרות לשנות את ערך הפרמטר בתוך הפונקציה.
  • ניתן להגדיר שפרמטרים אלה יועברו כמשתני הפניה (reference variable), כלומר, שהמשתנים המקוריים לא יועתקו, אלא יועברו מצביעים אליהם. כך ניתן לשנות בעזרת פונקציה את ערכיהם של אובייקטים שהם לא חלק מהמשתנים הפנימיים של הפונקציה. צורה זו מונעת את הצורך להשתמש באופרטור & בקריאה על מנת להעביר את כתובת המשתנה.
  • ניתן להגדיר שפרמטרים מסוימים הם אופציונאלים ובעלי ערך ברירת מחדל. במידה ולא הוזן להם ערך, ערכם יקבע על ידי ערך ברירת המחדל שהוזן על ידי כותב הפונקציה.

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

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

פונקציות inline

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

מהדרים מודרניים מבצעים, במקרים רבים, טיוב ביצועים כנזכר מעלה על דעת עצמם, ללא סימון זה בגוף הקוד.

מבנה struct

מבנה struct הורחב ויכול לכלול בתוכו מלבד משתנים גם מתודות (פונקציות המשויכות אליו), והוא למעשה מוגדר כמחלקה (class), עם גישה למשתנים בהרשאות public בברירת המחדל.

מחלקה class

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

העמסת אופרטורים

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

הגבלת גישה

ישנן שלוש רמות של הגבלות גישה למשתנים ולשיטות של אובייקט (או של מחלקה):

  • private - פרטי שרק משתני המחלקה יכולים להשתמש בה (וגם מחלקה שירשה את תכונתיה דרך public)
  • protected-שמור רק למחלקה וגם למחלקות שיורשות ממנה (גם דרך private)
  • public - כללי לכולם יש גישה אליה

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

הגבלות הגישה תקפות גם לגבי שיטות ומשתנים שמוגדרים ברמת המחלקה (static).

הורשה

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

השפה תומכת גם בפולימורפיזם: ניתן להתייחס לאובייקט דרך מצביע למחלקה שהוא צאצא שלה, ולהפעיל פונקציות של האובייקט (עם מימוש ספציפי לאובייקט) אם הוגדרו בממשק של המחלקה ממנה הוא נורש. מנגנון ה־Run-Time Type Information (‏RTTI) מאפשר לקבל מידע, תוך כדי ריצת התוכנית, על טיבו של המשתנה ולאפשר המרת טיפוסים בטוחה.

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

  • ירושה פרטית (private) - מגבילה את הרשאת הגישה של המשתנים והשיטות ל-private
  • ירושה ציבורית (public) - יורשת את כל המשתנים והשיטות באותה רמת גישה
  • ירושה שמורה (protected) - מגבילה את הרשאת הגישה של המשתנים והשיטות ל-protected (כלומר public הופך ל-protected)


תבניות

שפת C++‎ תומכת ב־templates – תבניות – שמאפשרות שימוש באותו קוד עבור טיפוסי נתונים שונים ופרמטרים שונים - בסיסיים או מוגדרי משתמש. המהדר (קומפיילר) מזהה אילו פרמטרים הועברו לתבנית ומשכפל את התבנית בהתאם. תוצר לוואי של אפשרות זו עלול להיות "ניפוח קוד", שכן עבור כל פרמטר שהועבר התבנית תשוכפל התבנית שוב ושוב.

ניתן ליצור מופעים מיוחדים של התבניות עבור פרמטרים ספיציפיים.

מבנים בשפה

ספרית התבניות הסטנדרטית (STL - Standard Template Library‎) מכילה מימושים של מבני נתונים רבים ויעילים (מחסנית, רשימה מקושרת, עץ חיפוש מאוזן ועוד), וכן טיפוסי נתונים סטנדרטיים חשובים כמו וקטור (מערך משוכלל) ומחרוזת. הספרייה גם מכילה אלגוריתמים גנריים שניתן להפעיל על מבני הנתונים כמו גם מחלקות לטיפול במספרים ובקלט־פלט.

תוספות אלו, תורשה מרובה (1989), העמסת אופרטורים (1989), תבניות (1991), ספרית התבניות הסטנדרטית ו־RTTI ‏(1995) הוכנסו לשפה בהדרגה.

תחביר


שגיאות פרמטריות בתבנית:להשלים

פרמטרי חובה [ נושא ] חסרים


טיפוסים

  • int
  • float
  • double
  • long double
  • char
  • unsigned long int
  • signed long int
  • long int
  • unsigned short int
  • signed short int
  • short int
  • signed int
  • unsigned int
  • signed char
  • unsigned char

קלט פלט

הקלט והפלט מתבצעים בשפה על ידי stream-ים מהם מבצעים קריאה באמצעות האופרטור << וכתיבה באמצעות האופרטור >>. טיפוסים אלו מוגדרים בעיקר באמצעות הספריות iostream (קלט/פלט סטנדרטי) ו-fstream (קלט/פלט באמצעות קבצים) ובמרבית המהדרים על ידי ספריות נוספות.

למשל תוך שימוש בהגדרת הקלט הסטנדרטי כ-cin והפלט הסטנדרטי כ-cout ניתן לכתוב:

int x;
cout<<"please enter a number: ";
cin>>x;

במקרה כאן הפלט יראה כך:

please enter a number:

והמחשב ימתין לקבלת מספר שלם.

הכרזות

מילים שמורות

asm auto bool break case catch
char class const const_cast continue default
delete do double dynamic_cast else enum
explicit export extern false float for
for friend goto if inline int
long mutable namespace new operator private
protected public register reinterpret_cast return short
signed sizeof static static_cast struct switch
template this throw true try typedef
typeid typename union unsigned using virtual
void volatile wchar_t while

אופרטורים

קיימים שלושה סוגים של אופרטורים:

  1. אופרטורים אונריים, בהם יש רק אופרנד אחד. למשל: c++
  2. אופרטורים בינאריים, בהם יש שני אופרנדים. למשל a * b
  3. אופרנד טרנרי אחד ויחיד, בו יש 3 אופרנדים הוא: a ? b : c

(משמעותו של האופרטור הטרינארי היא: נבדוק את התנאי a, שיכול להיות ביטוי כלשהו, אם הוא מתקיים, נבצע את b, אחרת נבצע את c )

מבנה בקרה


שגיאות פרמטריות בתבנית:להשלים

פרמטרי חובה [ נושא ] חסרים

פונקציות/שיטות

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

הצהרה

הצהרה על פונקציה היא מהצורה:

type_specifier function_name (parameter list);

כאשר:

  • type_specifier - סוג הערך המוחזר על ידי הפונקציה (int ,long...)
  • function_name - שם הפונקציה (חייב להיות מזהה חוקי)
  • parameter list - פרמטרי הפונקציה הם רצף מופרד של הגדרות פרמטרים מהצורה הבאה:
type parameter = default_value
כאשר:
  • type - טיפוס הפרמטר
  • parameter - שם הפרמטר (חייב להיות ייחודי בתוך ההצהרה)
  • default_value - ערך ברירת המחדל של הפרמטרים (פרמטרים בעלי ערכים כאלו חייבים להופיע בסוף ההצהרה)
בתור פרמטר אחרון יכול להופיע במקום הצורה הנזכרת לעיל הצירוף ... המציין כי מספר הפרמטרים לפונקציה משתנה (בדומה ל-C).

ההצהרות מופיעות לרוב בקובצי .h המהווים את הצהרת הממשק של המחלקה אולם ניתן לכתוב הצהרות גם בקובצי .cpp רגילים (דבר המקובל בעיקר כאשר הפונקציות מקיימות רקורסיה הדדית).

הגדרות

הגדרת פונקציה או שיטה דומה מאוד להצהרה עליה והיא מהצורה:

inline type_specifier class::function_name (parameter list)
{
code
}

כאשר:

  • inline - אם מופיע מציין כי זאת פונקציית inline (שיטות המופיעות בגוף ההצהרה על מחלקה מוגדרות אוטומטית כ-inline)
  • type_specifier - זהה להצהרה
  • class - נדרש אם השיטה מוגדרת מחוץ לבלוק של הצהרת המחלקה, במקרים האחרים ערך זה (וה-:: אחריו) מושמט
  • function_name - זהה להצהרה
  • parameter list - זהה להצהרה (למעט ערכי ברירת מחדל הניתנים להשמטה)
  • code - הקוד של השיטה או הפונקציה (אם טיפוס ערך ההחזר איננו void חייב להופיע משפט return מתאים)

קריאה

קריאה לפונקציה או לשיטה היא בצורה:

object.name(parameter_list)

כאשר:

  • object - הוא שם האובייקט עליו מופעלת השיטה או המחלקה אליה שייכת השיטה (אם הפונקציה איננה חלק ממחלקה, ערך זה וסימן הנקודה מושמטים, כמו כן ניתן להשמיט ערך זה אם השיטה מופעלת על האובייקט הנוכחי).
  • name - שם הפונקציה או השיטה
  • parameter_list - הפרמטרים המועברים לפונקציה או לשיטה (מספר המשתנים וסוגם קובע את הפונקציה בה משתמשים בפועל במקרה של העמסת פונקציות).

דוגמה

דוגמה לשימוש בפונקציות היא:

#include <iostream>

using namespace std;

int max(int x, int y);

int max(int x, int y)
{
    if (x > y)
        return x;
    else
        return y;
}

int main()
{
    int a, b;
    cout << "Please enter two numbers\n";
    cin >> a >> b;
    cout << max(a, b);
    return 0;
}

שלום עולם

תוכנית שלום עולם בשפת C++‎ תראה כך:

#include <iostream>

int main()
{
    std::cout << "Hello, world!"<<std::endl;
    return 0;
}

ראו גם

לקריאה נוספת

  • Stroustrup, Bjarne (2000). The C++ Programming Language, Special Edition, Addison-Wesley. ISBN 0-201-70073-5.
  • Stroustrup, Bjarne (1994). The Design and Evolution of C++. Addison-Wesley. ISBN 0-201-54330-3.
  • Meyers Scott (2005). Effective C++: 55 Specific Ways to Improve Your Programs and Designs, 3rd Edition, Addison-Wesley. ISBN 0-321-33487-6.
  • Meyers Scott (1995). More Effective C++: 35 New Ways to Improve Your Programs and Designs, Addison-Wesley. ISBN 0-201-63371-X.

קישורים חיצוניים

הערות שוליים

  1. ^ תוכניתן, תכנן נכון, אתר דהמרקר‏


תבנית:שפות תכנות