AudaNix

دالة هدم الفئة Destructors

1 مشاركة في هذا الموضوع

دالة هدم الفئة Destructors

دالة هدم الفئة

تعبتر دالة هدم الفئة نوع خاص من دوال أعضاء الفئة التى يتم استدعائها عن حذف الكائن من الذاكرة. وتعتبر الداله المقابلة لدالة البناء. يتم استدعاء داله هدم الفئة لكي تساعد فى حذف الذاكرة التى تم حجزها بداخل الفئة فى حالتين:

  1. يتم استدعاء داله هدم الفئة عندما يتم حذف الفئة بشكل مباشر بأستخدام delete.
  2. يتم استدعاء داله هدم الفئة عندما تخرج الفئة من نطاق (code block) الكود الحالي.

(النقطتين السابقتين تحد مع كل المتغيرات سواء العادية او الديناميكية)

بالنسبة للفئات البسيطة قد لاتتطلب دالة هدم بسبب قيام سي++ بالعمل على حذف الذاكرة التى لم تعد بحاجة لها بالنيابة عنك. وعلى الرغم من ذلك ان كانت لديك ذاكرة محجوزة ديناميكينا او بحاجة الى اجراء بعض الاعمال قبل حذف الفئة(مثل: اغلاق ملف) فأن دالة الهدم المكان المناسب لفعل ذلك.

مثل دالة البناء فأن دالة الهدم لها مجموعة من القواعد عند تسميتها:

  1. دالة الهدم لها نفس اسم الفئة مسبوقة بعلامة التلدة (~).
  2. دالة الهدم لاتأخذ اية وسائط.
  3. دالة الهدم لاترجع اي نوع من البيانات. كما لاتوجد طريقة للتحميل الزائد على دالة الهدم لانه لا يسمح بتوقيع مختلف متمثل فى تعدد الوسائط(لايوجد لها وسائط لكي نميز بين داله هدم واخرى حتى يعمل مفهموم التحميل الزائد على داله الهدم).

لاحظ ان القاعدة 2 تنطبق فقط على دالة هدم واحدة محتمل ان تكون لكل فئة.

المثال على يستخدم دالة هدم بسيطة فى فئة نصية :

class MyString
{
private:
char *m_pchString;
int m_nLength;

public:
MyString(const char *pchString="")
{
// إيجاد طول السلسلة النصية
// بالاضافة الى حرف واحد لعلامة نهاية السلسلة النصية.
m_nLength = strlen(pchString) + 1;

// بعد حجز مساحة ذاكرة كافية لطول الفئة.
m_pchString = new char[m_nLength];

// نسخ وسائط الدالة الى الذاكرة.
strncpy(m_pchString, pchString, m_nLength);

// التأكد من اضافة علامة السلسلة النصية
m_pchString[m_nLength-1] = '\0';
}

~MyString() // دالة الهدم
{
// نحن نحتاج الى حذف الذاكرة التى حجزناها مسبقا
delete[] m_pchString;

// تعيين القية null للمتغير m_pchString اى لا شئ.
m_pchString = 0;
}

char* GetString() { return m_pchString; }
int GetLength() { return m_nLength; }
};
تعال نري كيف نستخدم هذة الفئة:
int main()
{
MyString cMyName("Alex");
std::cout << "My name is: " << cMyName.GetString() << std::endl;
return 0;
} // دالة الهدم cMyName يتم استدعائها هنا.

المخرجات:

My name is: Alex

فى السطر الاول قمنا متغير جديد من نوع MyString (أو عمل نسخة جديدة من الفئة MyString) وتمرير له السلسلة النصية "Alex" وبهذا نستدعي دالة البناء التى تقوم بحجز ذاكرة ديناميكية لكي تحمل السلسلة النصية المررة اليها. يجب استخدام حجز الذاكرة الديناميكي باستخدام new لاننا لانعرف مقدما كم يبلغ طول السلسلة النصية التى ينوي تمريرها المستخدم.

وفى نهاية main() فأن cMyName تخرج عن نطاق الدالة الرئيسية main() . لذا يتم استدعاء دالة هدم الفئة ~MyString() التي تحذف الذاكرة التى تم حجزها فى دالة بناء الفئة!

توقيت عمل دالة البناء والهدم للفئة.

كما وضحنا سابقا فأن دالة بناء الفئة يتم استدعائها عن كل مرة يتم فيها انشاء كائن جديد(نسخة جديدة من الفئة) ويتم استدعاء دالة هدم الفئة عندما يتم حذف الكائن من الذاكرة. فى المثال التالي نستخدم جملة cout بداخل دالتي بناء وهدم الفئة لكي نوضح الفكرة:

class Simple
{
private:
int m_nID;

public:
Simple(int nID)
{
std::cout << "Constructing Simple " << nID<< std::endl;
m_nID = nID;
}

~Simple()
{
std::cout << "Destructing Simple" << m_nID << std::endl;
}

int GetID() { return m_nID; }
};

int main()
{
// حجز مساحة للمتغير بشكل عادي فى قسم ذاكرة المكدس stack:
Simple cSimple(1);
std::cout << cSimple.GetID() << std::endl;

// حجز مساحة للمتغير فى الذاكرة الديناميكية
Simple *pSimple = new Simple(2);
std::cout << pSimple->GetID() << std::endl;
delete pSimple;

return 0;
} // يخرج الكائن cSimple عن نطاق الدالة main() هنا.

فأن مخرجات البرنامج كالتالي:

Constructing Simple 1
1
Constructing Simple 2
2
Destructing Simple 2
Destructing Simple 1

الى ان نلتقى فى درس جديد ان شاء الله

تم تعديل بواسطه محمد عودة
اخطاء كتابة
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .