הורס וירטואלי ב-C++

Hwrs Wyrtw Ly B C



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

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

מדוע אנו משתמשים ב-Virtual Destructor?

כאשר הביצוע של פונקציות חבר הכיתה מסתיימת או הפעלת המתודה main() עומדת להסתיים, ה-destructor נקרא אוטומטית כדי לשחרר את הזיכרון שהוקצה במהלך יצירת האובייקט. עכשיו, למה אנחנו משתמשים בהרס וירטואלי? כאשר נמחקת מחלקת הבסיס שמצביעה על המחלקה הנגזרת, כאן נעשה שימוש במצביע (*). משמיד מחלקות הבסיס נקרא רק במהלך תהליך זה. משמיד הכיתה הנגזר אינו נקרא מה שמוביל לבעיות. אחד מהם הוא בעיית דליפת זיכרון. כדי להימנע מבעיה זו ולהפוך את הקוד שלנו לאבטח, אנו משמידים למעשה את האובייקטים כדי לפנות את שטח הזיכרון שהוקצה במהלך יצירת האובייקטים על ידי מחיקת ה-base class destructor.

C++ דוגמה בסיסית ללא Virtual Destructor

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

קוד:

#include

באמצעות מרחב שמות std ;
class Parent_Class0
{
פּוּמְבֵּי :
הורה_כיתה0 ( )
{ cout << 'בונה כיתת הורים' << endl ; }
~הורים_כיתה0 ( )
{ cout << 'הורס כיתת הורים' << endl ; }
} ;
כיתה ילד_1 : Parent_Class ציבורי0
{
פּוּמְבֵּי :
ילד_1 ( )
{ cout << 'בנאי כיתת ילדים' << endl ; }
~ילד_1 ( )
{ cout << 'משמיד כיתות ילדים' << endl ; }
} ;
int רָאשִׁי ( )
{
הורה_כיתה0 * מַצבִּיעַ = ילד חדש_1 ( ) ;
מחק מצביע ;
לַחֲזוֹר 0 ;
}

קוד זה מסביר כיצד הקוד פועל ללא הורס וירטואלי. קודם כל, צור מחלקה בשם 'Prent_Class0' שתהיה מחלקת האב. בתוך המחלקה הזו, צור בנאי והרס. כפי שאנו יודעים, הקונסטרוקטור וההרס נקראים זהה לשם המחלקה. ההורס מיוצג באופן דומה לבנאי אך יש לו סמל (~) המבדיל אותו מהקונסטרוקטור. בתוך הקונסטרוקטור וההרס, הדפס הודעה באמצעות 'cout<<'. כעת, צור מחלקה נוספת שהיא 'Child_1'. מחלקה זו נגזרת ממחלקת האב, 'Prent_Class0'. למחלקה הנגזרת יש הבנאי וההרס המכילים הודעה להדפסה על מסך הפלט.

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

תְפוּקָה:

C++ דוגמה עם Virtual Destructor

בואו נדון במשמיד הווירטואלי עם קוד פשוט כדי להבדיל איך הוא עובד עם ובלי משמיד וירטואלי.

קוד:

#include

באמצעות מרחב שמות std ;
class Parent_Class0
{
פּוּמְבֵּי :
הורה_כיתה0 ( )
{ cout << 'בונה כיתת הורים' << endl ; }
וירטואלי ~ Parent_Class0 ( )
{ cout << 'הורס כיתת הורים' << endl ; }
} ;
כיתה ילד_1 : Parent_Class ציבורי0
{
פּוּמְבֵּי :
ילד_1 ( )
{ cout << 'בנאי כיתת ילדים' << endl ; }
וירטואלי ~ילד_1 ( )
{ cout << 'משמיד כיתות ילדים' << endl ; }
} ;
int רָאשִׁי ( )
{
הורה_כיתה0 * מַצבִּיעַ = ילד חדש_1 ( ) ;
מחק מצביע ;
לַחֲזוֹר 0 ;
}

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

תְפוּקָה:

C++ דוגמה של Pure Virtual Destructor

בקוד זה, נדבר על ההורס הווירטואלי הטהור, איך הוא עובד, וכיצד הוא שונה מההרס הווירטואלי.

קוד:

#include

כיתה הורה_0 {
פּוּמְבֵּי :
וירטואלי ~הורה_0 ( ) = 0 ;
} ;
הורה_0 :: ~הורה_0 ( )
{
סטד :: cout << 'שלום אני משמיד טהור. קראת לי!' ;
}
כיתה ילד_0 : הורה ציבורי_0 {
פּוּמְבֵּי :
~ילד_0 ( ) { סטד :: cout << 'הרס נגזר נמצא כאן \n ' ; }
} ;

int רָאשִׁי ( )
{
הורה_0 * ptr_0 = ילד חדש_0 ( ) ;
מחק ptr_0 ;
לַחֲזוֹר 0 ;
}

מחלקת האב 'Prent_0' נוצרת בשלב הראשון של הקוד. בתוכו, צור את ה-Virtual Destructor והקצה לו 0. זה מגדיר את ה-Virtual Destructor ל-Virtual Destructor טהור, מה שאומר שמחלקת האב מופשטת כעת ולא נוכל ליצור את המופעים של המחלקה הזו. מחוץ למחלקת האב 'Parent_0', הגדירו את ההורסים ואת std::cout. הטקסט הנדרש מוצג על ידי שימוש ב-std::cout. לאחר מכן, הפק מחלקה 'Child_0' ממחלקת האב והגדר את המשמיד שלה. בתוך ההרס, הדפס הודעה. בפונקציה main(), צור את המצביע של מחלקת האב והקצה לה את מחלקת הילד.

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

תְפוּקָה:

סיכום

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