المُنشئات والمُدمرات (Constructors & Destructors)

كل كائن في C++ يمرّ بدورتين أساسيتين في حياته:

  • الولادة (الإنشاء)
  • الموت (التدمير)

واللي بيتولّى المهمتين هدول هما:

  • المنشئ (Constructor)
  • المدمّر (Destructor)

هالآليتين هما العمود الفقري لإدارة الكائنات في البرمجة الكينونية، سواء كنت تبني تطبيق بسيط أو نظام ضخم فيه عشرات الفئات.


🚀 1. ما هو الـ Constructor؟

الـ Constructor (المنشئ) هو دالة خاصة داخل الفئة تُنفَّذ تلقائيًا عند إنشاء كائن جديد منها.
ما بتحتاج تستدعيها بنفسك — هي بتشتغل لحالها وقت “ولادة الكائن”.


⚙️ تعريفه:

  • له نفس اسم الفئة تمامًا.
  • لا يُعيد أي نوع (حتى void ❌).
  • يُستخدم لتهيئة القيم الابتدائية للكائن (initialization).
  • يمكن أن يكون بأكثر من شكل (Overloaded).

📘 مثال على Constructor افتراضي (Default Constructor)

#include <iostream>
using namespace std;

class Car {
public:
    string brand;
    int year;

    // Constructor افتراضي
    Car() {
        brand = "Unknown";
        year = 0;
        cout << "تم إنشاء كائن جديد من Car!" << endl;
    }

    void showInfo() {
        cout << "الماركة: " << brand << " | سنة الصنع: " << year << endl;
    }
};

int main() {
    Car c1;  // وقت الإنشاء يتم استدعاء الـ Constructor تلقائيًا
    c1.showInfo();
    return 0;
}

📤 النتيجة:

تم إنشاء كائن جديد من Car!
الماركة: Unknown | سنة الصنع: 0

🔹 هذا هو المنشئ الافتراضي (Default Constructor) — يُستخدم عندما لا يتم تمرير أي بيانات أثناء إنشاء الكائن.


🧩 2. المنشئ المُعامل (Parameterized Constructor)

أحيانًا نريد نمرر قيم عند إنشاء الكائن — بدل ما نعيّنها بعدين.
هون بيجي دور المنشئ المُعامل (Parameterized Constructor).


📘 مثال:

#include <iostream>
using namespace std;

class Car {
public:
    string brand;
    int year;

    // Constructor بمعاملات
    Car(string b, int y) {
        brand = b;
        year = y;
        cout << "تم إنشاء سيارة جديدة: " << brand << endl;
    }

    void showInfo() {
        cout << "الماركة: " << brand << " | سنة الصنع: " << year << endl;
    }
};

int main() {
    Car c1("BMW", 2020);
    Car c2("Tesla", 2024);

    c1.showInfo();
    c2.showInfo();

    return 0;
}

📤 النتيجة:

تم إنشاء سيارة جديدة: BMW
تم إنشاء سيارة جديدة: Tesla
الماركة: BMW | سنة الصنع: 2020
الماركة: Tesla | سنة الصنع: 2024

🔹 هنا المنشئ استقبل قيمتين مباشرة وقت إنشاء الكائن، وعيّنهم في خصائصه.


⚙️ 3. أنواع Constructors في C++

النوعالوصف
Default Constructorيُستدعى تلقائيًا عند إنشاء الكائن بدون معاملات.
Parameterized Constructorيُستخدم لإرسال بيانات أثناء الإنشاء.
Copy Constructorيُستخدم لنسخ كائن موجود إلى كائن جديد.
Dynamic Constructorيُستخدم مع الذاكرة الديناميكية (new).

(رح نحكي عن Copy Constructor بالتفصيل لاحقًا إن شاء الله.)


🧠 4. لماذا نحتاج Constructors؟

  • لتهيئة البيانات فور إنشاء الكائن.
  • لتفادي الخطأ الناتج عن استخدام قيم غير مهيأة.
  • لتقليل التكرار في الكود (Initialization logic).
  • لتوفير مرونة في إنشاء الكائنات بطرق مختلفة (Overloading).

5. دوال المُنشئ الزائد (Constructor Overloading)

تقدر تعمل أكثر من منشئ بنفس الاسم لكن بمعاملات مختلفة.

📘 مثال عملي:

#include <iostream>
using namespace std;

class Rectangle {
public:
    int width, height;

    // Constructor 1
    Rectangle() {
        width = 0;
        height = 0;
    }

    // Constructor 2
    Rectangle(int w, int h) {
        width = w;
        height = h;
    }

    void show() {
        cout << "العرض: " << width << ", الارتفاع: " << height << endl;
    }
};

int main() {
    Rectangle r1;           // يستدعي الـ Default
    Rectangle r2(10, 20);   // يستدعي الـ Parameterized

    r1.show();
    r2.show();
}

📤 النتيجة:

العرض: 0, الارتفاع: 0
العرض: 10, الارتفاع: 20

💣 6. المدمّر (Destructor)

المدمّر هو الدالة اللي تُنفّذ تلقائيًا عند نهاية حياة الكائن — لما يخرج من النطاق أو يتم حذفه من الذاكرة.

هو المسؤول عن “تنظيف الموارد” مثل:

  • إغلاق الملفات المفتوحة
  • تحرير الذاكرة المحجوزة
  • قطع الاتصال مع قواعد البيانات
  • وأي عملية تنظيف أخرى

⚙️ قواعد المدمّر:

  • اسمه نفس اسم الفئة، لكنه يبدأ برمز (~).
  • لا يستقبل معاملات.
  • لا يُعيد أي قيمة.
  • يُستدعى تلقائيًا عند تدمير الكائن.

📘 مثال على Destructor:

#include <iostream>
using namespace std;

class FileHandler {
public:
    FileHandler() {
        cout << "تم فتح الملف." << endl;
    }

    ~FileHandler() {
        cout << "تم إغلاق الملف." << endl;
    }
};

int main() {
    FileHandler file;  // يتم استدعاء Constructor عند الإنشاء
    cout << "نعمل على الملف..." << endl;
} // عند نهاية البرنامج يتم استدعاء Destructor تلقائيًا

📤 النتيجة:

تم فتح الملف.
نعمل على الملف...
تم إغلاق الملف.

🔹 لاحظ كيف تم استدعاء المدمّر تلقائيًا بدون ما نكتب أي شيء، بمجرد انتهاء عمر الكائن.


🔄 7. التسلسل الزمني لحياة الكائن (Object Lifecycle)

  1. الإنشاء (Creation) → يستدعي Constructor
  2. الاستخدام (Usage) → الكائن يعمل عادي
  3. النهاية (Destruction) → يستدعي Destructor

⚙️ 8. المدمّر في الكائنات الديناميكية

عند استخدام new و delete يجب استدعاء المدمّر يدويًا باستخدام delete.

#include <iostream>
using namespace std;

class Test {
public:
    Test() { cout << "تم الإنشاء.\n"; }
    ~Test() { cout << "تم التدمير.\n"; }
};

int main() {
    Test* t = new Test(); // Constructor
    delete t;             // Destructor
}

📤 النتيجة:

تم الإنشاء.
تم التدمير.

🧱 9. مثال عملي شامل:

#include <iostream>
using namespace std;

class Employee {
private:
    string name;
    int age;

public:
    // Default Constructor
    Employee() {
        name = "غير معروف";
        age = 0;
        cout << "تم إنشاء موظف جديد (افتراضي)\n";
    }

    // Parameterized Constructor
    Employee(string n, int a) {
        name = n;
        age = a;
        cout << "تم إنشاء الموظف: " << name << endl;
    }

    void showInfo() {
        cout << "الاسم: " << name << " | العمر: " << age << endl;
    }

    // Destructor
    ~Employee() {
        cout << "تم حذف الموظف: " << name << endl;
    }
};

int main() {
    Employee e1;
    Employee e2("محمد", 25);
    e1.showInfo();
    e2.showInfo();

    cout << "نهاية البرنامج.\n";
    return 0;
}

📤 النتيجة:

تم إنشاء موظف جديد (افتراضي)
تم إنشاء الموظف: محمد
الاسم: غير معروف | العمر: 0
الاسم: محمد | العمر: 25
نهاية البرنامج.
تم حذف الموظف: محمد
تم حذف الموظف: غير معروف

لاحظ الترتيب:

  • الإنشاء من الأعلى للأسفل.
  • التدمير بالعكس (آخر كائن يُنشأ هو أول من يُدمّر).

🧠 10. ملخص سريع

العنصرالتوصيف
Constructorدالة تُنفّذ عند إنشاء الكائن.
Destructorدالة تُنفّذ عند انتهاء عمر الكائن.
Default Constructorبدون معاملات.
Parameterized Constructorيقبل معاملات لتهيئة الكائن.
Destructorلا يقبل معاملات ولا يُعيد قيمة.

🌍 11. روابط خارجية موثوقة

🔗 cppreference – Constructors & Destructors
https://en.cppreference.com/w/cpp/language/constructor
https://en.cppreference.com/w/cpp/language/destructor

🔗 GeeksForGeeks – Constructors in C++
https://www.geeksforgeeks.org/constructors-c/

🔗 W3Schools – C++ Constructors and Destructors
https://www.w3schools.com/cpp/cpp_constructors.asp


🧩 الخلاصة

المنشئات والمُدمّرات هما القلب اللي بينبض داخل كل كائن:

  • Constructor هو اللي “يخلق” الكائن ويهيئه.
  • Destructor هو اللي “يمسحه من الذاكرة” وينظّف وراءه.

الفهم العميق لهما هو مفتاحك لفهم إدارة الذاكرة في C++، خصوصًا لما تدخل لاحقًا في:

  • الكائنات الديناميكية
  • الوراثة (Inheritance)
  • إدارة الموارد (RAII)
  • والمفاهيم المتقدمة مثل Smart Pointers

اكتشاف المزيد من كود التطور

اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.

اترك رد

Scroll to Top