أداة الهدم Destructor
ما هو الـDestructor؟
في لغة C++، تعتبر أداة الهدم destructor دالة عضو خاصة يتم استدعاؤها تلقائيًا عندما يخرج كائن عن النطاق أو يتم حذفه بشكل صريح. والغرض الأساسي منه هو تنظيف الموارد أو تنفيذ الإجراءات قبل إلغاء تخصيص ذاكرة الكائن.
خصائص الـDestructor :
- الإسم والبناء:
الاسم: الـDestructors لها نفس اسم الفئة class، مسبوقة بعلامة التلدة (~).
بناء الجملة: ~ClassName() - الاستدعاء التلقائي:
يتم استدعاء أدوات الهدم تلقائيًا عندما يخرج كائن عن النطاق أو يتم حذفه بشكل صريح.
أداة الهدم تتعامل مع تنظيف وإلغاء تخصيص الموارد التي يحتفظ بها الكائن. - لا يوجد نوع إرجاع أو Parameters:
لا تحتوي أدوات الهدم على الإرجاع، ولا حتى void.
لا تقبل أي parameters. - أداة هدم واحدة لكل class:
يمكن أن يحتوي كل class على أداة هدم واحدة فقط.
وهو مسؤول عن تنظيف الموارد المخصصة خلال عمر الكائن. - الحذف اليدوي:
بالنسبة للكائنات التي تم إنشاؤها ديناميكيًا باستخدام new، يتم استدعاء أداة الهدم destructor بشكل صريح باستخدام الحذف.
يعد هذا ضروريًا لتحرير الذاكرة المخصصة في الـheap. - تنظيف الموارد:
غالبًا ما يتم استخدام أدوات الهدم لتحرير الموارد مثل الذاكرة الديناميكية وhandles الملفات واتصالات قاعدة البيانات وما إلى ذلك.
يضمن التنظيف المناسب قبل تدمير الكائن.
لماذا نستخدم الـDestructors؟
تعد أدوات الهدم ضرورية لإدارة الموارد بشكل سليم والحفاظ على سلامة برنامجك. وهي مفيدة بشكل خاص عند التعامل مع تخصيص الذاكرة الديناميكية أو معالجة الملفات أو أي موقف يكون فيه التنظيف ضروريًا.
بناء جملة الـDestructor:
بناء جملة الهدم واضح ومباشر. له نفس اسم class ال`ي يسبقه الإشارة (~). هنا مثال:
class MyClass { public: // Constructor MyClass() { // Constructor code } // Destructor ~MyClass() { // Destructor code } };
مثال 1:
#include <iostream> using namespace std; class Rectangle { private: int W, H; public: Rectangle(int a, int b) { W = a; H = b; cout << "A rectangle has been created\n"; } ~Rectangle() { cout << W << " " << H << " A rectangle has been deleted\n"; } }; int main() { Rectangle R1(3, 4), R2(5, 6); return 0; }
يحدد هذا الكود class يسمى rectangle تمثل مستطيلاً بمتغيرات الأعضاء الخاصة W (العرض) وH (الارتفاع). تتضمن الفئة أداة بناء constructor لإنشاء مستطيل وأداة هدم destructor لتنظيف الموارد عند حذف المستطيل. دعونا نحلل الكود:
– تعريف الـ(Class): Rectangle
class Rectangle { private: int W, H; public: // Constructor Rectangle(int a, int b) { W = a; H = b; cout << "A rectangle has been created\n"; } // Destructor ~Rectangle() { cout << W << " " << H << " A rectangle has been deleted\n"; } };
- أداة البناء Constructor:
تهيئة متغيرات الأعضاء W (العرض) وH (الارتفاع) مع القيم التي تم تمريرها كـarguments.
طباعة رسالة تشير إلى إنشاء rectangle . - أداة الهدم Destructor:
طباعة رسالة بأبعاد المستطيل عند حذفها.
الدالة الرئيسة main:
int main() { // Creating two objects of class Rectangle Rectangle R1(3, 4), R2(5, 6); return 0; }
- إنشاء الكائن object:
يتم إنشاء كائنين، R1 وR2، من النوع Rectangle في الدالة الرئيسية. - تنفيذ أداة البناء Constructor :
يتم تنفيذ constructor فئة Rectangle لكل كائن، مع تهيئة عرضه وارتفاعه.
تتم طباعة رسائل تشير إلى إنشاء المستطيلات. - هدم الكائن Object Destruction:
عند خروج البرنامج، أو عند ترك نطاق الدالة الرئيسة، يتم استدعاء أدوات الهدم لـ R1 وR2 تلقائيًا.
تتم طباعة رسائل تشير إلى حذف المستطيلات وأبعادها.
مخرجات هذا البرنامج ستكون كالتالي:
A rectangle has been created A rectangle has been created 5 6 A rectangle has been deleted 3 4 A rectangle has been deleted
يوضح هذا الإخراج الاستدعاء التلقائي للـconstructor عند إنشاء الكائنات والاستدعاء للـdestructor عندما تخرج الكائنات عن النطاق (في نهاية البرنامج في هذه الحالة). تقوم أداة الهدم بطباعة رسائل تشير إلى حذف المستطيلات مع أبعادها.
مثال 2:
#include <iostream> using namespace std; class Rectangle { private: int W, H; public: Rectangle(): W(0), H(0) { cout << "W = " << W << " H = " << H << endl; } Rectangle(int a, int b): W(0), H(0) { W = a; H = b; cout << "A rectangle has been created\n"; Rectangle ob; } ~Rectangle() { cout << W << " " << H << " A rectangle has been deleted\n"; } }; int main() { Rectangle R1(3, 4), R2(5, 6); Rectangle R3; return 0; }
- Default Constructor:
تهيئة W وH إلى 0.
يطبع القيم الأولية لـ W وH عند إنشاء كائن باستخدام هذا الـconstructor. - Parameterized Constructor:
يقبل الـ(parameters) a وb لتعيين أبعاد المستطيل.
تهيئة W وH إلى 0 قبل تعيين القيم المُدخلة.
طباعة رسالة تشير إلى إنشاء rectangle .
ينشئ كائنًا آخر داخل الـconstructor (لا ينصح به). - أداة الهدم Destructor:
طباعة رسالة بأبعاد المستطيل عند حذفها.
مخرجات هذا البرنامج ستكون كالتالي:
A rectangle has been created W = 0 H = 0 0 0 A rectangle has been deleted A rectangle has been created W = 0 H = 0 0 0 A rectangle has been deleted W = 0 H = 0 0 0 A rectangle has been deleted 5 6 A rectangle has been deleted 3 4 A rectangle has been deleted
مثال 3:
#include <iostream> using namespace std; class phone { private: char name[10]; char model[10]; int price; public: phone() {} phone(char n[], char m[], int p) { strcpy(name, n); strcpy(model, m); price = p; } void print(); ~phone(); }; phone::~phone() { cout << "object destructed\n" } void phone::print() { cout << "Name = " << name << endl; cout << "Model = " << model << endl; cout << "Price = " << price << endl; } int main() { phone ob1, ob2("HUAWI", "MATE 9", 400); ob2.print(); return 0; }
يحدد هذا الكود class phoneيمثل هاتفًا يحتوي على متغيرات الأعضاء الخاصة، الاسم والطراز والسعر. تتضمن الفئة default constructor، وparameterized constructor، ودالة عضو (print)، وdestructor. دعونا نحلل الكود:
– تعريف الـ(Class): phone
class phone { private: char name[10]; char model[10]; int price; public: // Default Constructor phone() {} // Parameterized Constructor phone(char n[], char m[], int p) { strcpy(name, n); strcpy(model, m); price = p; } // Member Function to Print Phone Details void print(); // Destructor ~phone(); };
- Default Constructor:
يتم توفير default constructor فارغ. - Parameterized Constructor:
يقبل الـ(parameters ) n (name)، وm (model)، وp (price) لتهيئة متغيرات أعضاء الكائن. - دالة العضو (print):
يعرض تفاصيل الهاتف بما في ذلك اسمه وموديله وسعره. - أداة الهدم Destructor:
يخرج رسالة عند هدم كائن من الفئة.
– تنفيذ أداة الهدم Destructor:
phone::~phone() { cout << "object destructed\n"; }
يتم تعريف الـdestructor خارج الفئة ويطبع رسالة عند هدم كائن من الفئة.
الدالة الرئيسة main:
int main() { phone ob1, ob2("HUAWI", "MATE 9", 400); ob2.print(); return 0; }
- إنشاء الكائن object:
يتم إنشاء كائنين، ob1 وob2، من النوع phone.
تتم تهيئة ob2 باستخدام parameterized constructor. - تفاصيل الطباعة:
يتم استدعاء دالة عضو الطباعة لـ ob2 لعرض تفاصيلها. - هدم الكائن Object Destruction:
عند خروج البرنامج، أو عند ترك نطاق الدالة الرئيسية، يتم استدعاء أدوات الهدم لـ ob1 وob2 تلقائيًا.
تتم طباعة رسالة تشير إلى أنه تم إتلاف الكائن.
مخرجات هذا البرنامج ستكون كالتالي:
Name = HUAWI Model = MATE 9 Price = 400 object destructed
توضح المخرجات إنشاء كائنات الهاتف وطباعتها وتدميرها، بما في ذلك استخدام parameterized constructor وdestructor.
مثال 4:
#include <iostream> #include <cstring> using namespace std; class Student { private: char name[20]; int ID; public: Student() { cout << "Object created\n"; } ~Student() { cout << "Object destructed\n"; } void Set_Name_ID(char n[], int id) { strcpy(name, n); ID = id; } void print(void) { cout << name << "\t" << ID << endl; } }; //end of class definition void F(Student S) { Student S1; S1 = S; S.Set_Name_ID("Sami", 12345); S.print(); S1.print(); } int main() { Student St1, St2; St1.Set_Name_ID("Ahmad", 11111); St2.Set_Name_ID("Ali", 22222); cout << "Going to Function\n"; F(St1); cout << "Back from Funcrion\n"; St1.print(); return 0; }
يحدد هذا الكودclass Student الذي يمثل الطالب مع اسم ومعرف متغيرات الأعضاء الخاصة. يتضمن الـ(class) default constructor، وdestructor، ودالة عضو لتعيين الاسم والمعرف، ودالة عضو أخرى لطباعة تفاصيل الطالب. بالإضافة إلى ذلك، هناك دالة F تأخذ Student object كـparameter وتوضح إنشاء الكائن وتعيينه وتعديله وهدمه داخل الدالة. دعونا نحلل الكود:
– تعريف الـ(Class): Student
class Student { private: char name[20]; int ID; public: // Default Constructor Student() { cout << "Object created\n"; } // Destructor ~Student() { cout << "Object destructed\n"; } // Member Function to Set Name and ID void Set_Name_ID(char n[], int id) { strcpy(name, n); ID = id; } // Member Function to Print Student Details void print(void) { cout << name << "\t" << ID << endl; } };
- Default Constructor:
طباعة رسالة تشير إلى إنشاء كائن. - أداة الهدم Destructor:
طباعة رسالة تشير إلى أن الكائن قد تم إتلافه. - دالة Set_Name_ID:
يقبل الـ(parameters) n (name) والـid (ID) لتعيين متغيرات الأعضاء. - دالة الطباعة print:
طباعة اسم وهوية الطالب.
– الدالة F:
void F(Student S) { Student S1; S1 = S; S.Set_Name_ID("Sami", 12345); S.print(); S1.print(); }
- يقوم بإنشاء Student object S1 داخل الدالة.
- نسخ محتوى الـ(parameter) S إلى S1.
- يعدل محتوى S باستخدام الدالة Set_Name_ID.
- يطبع تفاصيل كل من S وS1.
الدالة الرئيسة main:
int main() { Student St1, St2; St1.Set_Name_ID("Ahmad", 11111); St2.Set_Name_ID("Ali", 22222); cout << "Going to Function\n"; F(St1); cout << "Back from Function\n"; St1.print(); return 0; }
- إنشاء الكائن وتعديله:
إنشاء كائنين للطالب، St1 وSt2.
يقوم بتعيين أسمائهم ومعرفاتهم باستخدام الدالة Set_Name_ID. - إستدعاء الدالة:
يستدعي الدالة F بتمرير St1 كـparameter. - هدم الكائن Object Destruction:
طباعة رسائل تشير إلى هدم الكائنات عند خروجها عن النطاق (نهاية الدالة أو البرنامج).
مخرجات هذا البرنامج ستكون كالتالي:
Object created Object created Going to Function Object created Sami 12345 Ahmad 11111 Object destructed Object destructed Back from Funcrion Ahmad 11111 Object destructed Object destructed
يوضح هذه المخرجات إنشاء كائنات الطالب وتعديلها وتدميرها، بما في ذلك سلوك الـconstructor والـdestructor الافتراضيين. توضح الدالة F نسخ الكائنات وتعديلها داخل الدالة.