Copy constructor

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

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

מבחינים בין שני סוגי העתקה:

  • "העתקה רדודה" (Shallow copy) - מבוצעת על ידי בנאי ההעתקה, ה-copy constructor, האוטומטי של שפת התכנות (כלומר שלאחר שהתוכנית עוברת אינפרטציה, ההדרה, שלבי ההעתקה נהפכים שקופים ומבוצעים לפי שיקולי המערכת מבלי שלמתכנת יש אפשרות לשלוט ולבקר אותה)
  • "העתקה עמוקה" (Deep copy), - כדי לחולל אותה נדרש המתכנת ליצור את בנאי ההעתקה בעצמו, בעיקר במקרה של מצביעים.

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

בשפת C++‎, לא ניתן להצהיר על בנאי העתקה, מבלי להצהיר על בנאי ברירת- מחדל (Default Constractor), אף על פי שהמהדר לרוב ייצור אותו על פי רצון המתכנת.

בבנאי ההעתקה הקריאה היא כך שההתייחסות היא לקבוע (const) ולא למשתנה (כלומר: const vaule&) המבטיח, שלא ישונה המשתנה של העצם המועתק.

ב־.NET וב־Java קיימת פונקציית Clone המוגדרת על מחלקת השורש (Object) המבצעת בתור ברירת המחדל העתקה רדודה וניתן לדרוס אותה כך שתבצע העתקה עמוקה (בשתי הסביבות אין Copy constructor).

דוגמה למימוש בתכנות (C++‎)[עריכת קוד מקור | עריכה]

class CPerson {
  int m_iAge;
  string m_szName;
  Person* m_pMother;
 
  public: CPerson(const CPerson& p) {
   m_iAge=p.m_iAge;
   m_szName=p.m_szName;
 
   //This check would make sense for an assignment operator, but not for a copy constructor,
   //since the object should always be a new one.
   //if (NULL != m_pMother) {
   //  delete(m_pMother);
   //  m_pMother = NULL;
   //}
 
   if (NULL != p.m_pMother) {
     m_pMother=new Person(p.m_pMother);
   }
  }
};