בנאי העתקה (בעברית: משבט) הוא מתודה של מחלקה שקוראים לה בעת יצירת מופע חדש כתוצאה מהעתקה של מופע קיים. בשפות מונחות עצמים שם המתודה זהה לשם המחלקה והיא מקבלת בדרך כלל התייחסות לקבוע (const reference). זה מונע שינוי בלתי מכוון של האובייקט שמעתיקים.
מבחינים בין שני סוגי העתקה: העתקה רדודה והעתקה עמוקה. העתקה רדודה מעתיקה רק את הערכים הפשוטים, כולל מצביעים (pointer), משתנה שמצביע על כתובת בזיכרון. כאשר מעתיקים מצביע ברדידות, שני האובייקטים משתמשים באותה כתובת. שינוי בתוכן הכתובת ישפיע על שניהם, וזה לרוב לא רצוי.
העתקה עמוקה יוצרת עותקים נפרדים גם של הנתונים המוצעים על ידי מצביעים. כך כל מופע מקבל העתק עצמאי של התוכן, ושינויים באחד לא ישפיעו על השני.
בשפת אין אפשרות להצהיר על בנאי העתקה מבלי להצהיר גם על בנאי ברירת־מחדל (Default Constructor), אף שהמהדר בדרך‑כלל ייצור אותו אוטומטית אם המתכנת לא מוצהר אותו. בבנאי העתקה הנפוץ ההתייחסות לפרמטר היא const value& (הכוונה: העברה כהפניית קבוע), שמבטיחה שאובייקט המקור לא ישתנה.
ב־.NET וב־Java קיימת פונקציית Clone המוגדרת במחלקת השורש Object. ברירת המחדל של Clone מבצעת העתקה רדודה, וניתן לדרוס אותה כדי לבצע העתקה עמוקה. בשתי הסביבות הללו אין Copy constructor כמושג מובנה.
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;
if (NULL != p.m_pMother) {
m_pMother = new Person(p.m_pMother);
}
}
בנאי העתקה, פונקציה שמייצרת עותק של עצם קיים. העתק = יצירת אותו דבר חדש.
יש שתי דרכים להעתקה. העתקה רדודה מעתיקה רק קישורים. קישור (מצביע) הוא משתנה שמצביע למקום בזיכרון. כשהעתקה רדודה מעתיקה קישור, שני העצמים מסתמכים על אותו מקום.
העתקה עמוקה מעתיקה גם את מה שהקישורים מפנים. כך כל עצם מקבל עותק נפרד. זה מונע בעיות כששינויים באחד משפיעים על השני.
בשפות מסוימות חייבים גם בנאי ברירת־מחדל (Default Constructor) כשמגדירים בנאי העתקה. בבנאי העתקה משתמשים בדרך‑כלל בהתייחסות לקבוע (const reference) כדי לא לשנות את המקור.
ב־.NET וב־Java יש פונקציה בשם Clone. היא מעתיקה ברירת מחדל באופן רדוד. אפשר לשנות אותה כדי להעתיק עמוק.
class CPerson { ... } // דוגמה שמראה העתקת שדות ומצביע לאם
תגובות גולשים