Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

المنشئ الافتراضي

جزء من قسم Object Oriented Programming في رحلة C++ على Coddy — الدرس 18 من 104.

إنّ المُنشئ الافتراضي (default constructor) هو مُنشئ يمكن استدعاؤه بدون أي وسائط. يقوم بتهيئة كائن عندما لا يتم توفير قيم أولية. تحتاج كل فئة (class) إلى طريقة لإنشاء كائنات في حالة افتراضية صالحة.

إذا لم تقم بتعريف أي منشئ (constructor)، فإن المترجم (compiler) ينشئ منشئاً افتراضياً ضمنياً لا يفعل شيئاً للأنواع الأولية (primitive types) ويستدعي المنشئات الافتراضية للكائنات الأعضاء (member objects).

class Player {
    int health;
    int score;
public:
    Player() {           // المنشئ الافتراضي
        health = 100;
        score = 0;
    }
};

Player p1;               // يستدعي المنشئ الافتراضي
Player p2{};             // يستدعي أيضاً المنشئ الافتراضي

بمجرد قيامك بتعريف أي منشئ (مثل المنشئ ذو المعاملات - parameterized)، لن يقوم المترجم (compiler) بإنشاء منشئ افتراضي (default constructor) بعد الآن. يجب عليك تعريف واحد صراحةً إذا كنت لا تزال بحاجة إليه.

class Enemy {
    int damage;
public:
    Enemy(int d) : damage(d) {}  // منشئ بمعاملات فقط
};

Enemy e1(10);    // يعمل
Enemy e2;        // خطأ! لا يوجد منشئ افتراضي

في لغة ++C الحديثة، يمكنك طلب المنشئ الافتراضي الذي يولده المترجم بشكل صريح باستخدام = default:

class Item {
    int id;
public:
    Item() = default;           // المترجم ينشئ المنشئ الافتراضي
    Item(int i) : id(i) {}
};

تعد المشيدات الافتراضية (Default constructors) ضرورية لإنشاء مصفوفات من الكائنات وللأصناف المستخدمة في الحاويات مثل std::vector، والتي قد تحتاج إلى إنشاء عناصر بدون وسائط.

challenge icon

التحدي

سهل

لنقم ببناء نظام عداد بسيط يوضح كيف تقوم المُنشئات الافتراضية (default constructors) بتهيئة الكائنات إلى حالة بداية صالحة.

ستقوم بإنشاء ملفين لتنظيم الكود الخاص بك:

  • Counter.h: قم بتعريف فئة Counter التي تتبع قيمة العداد. يجب أن تحتوي الفئة الخاصة بك على:
    • سمة count خاصة (عدد صحيح)
    • سمة name خاصة (سلسلة نصية) لتحديد العداد
    • مُنشئ افتراضي يقوم بتهيئة count إلى 0 و name إلى "Unnamed"، ثم يطبع "Counter created: <name>"
    • طريقة increment() تزيد العداد بمقدار 1
    • طريقة getCount() ترجع قيمة العداد الحالية
    • طريقة getName() ترجع اسم العداد
  • main.cpp: وضح أن المُنشئات الافتراضية تعمل عند إنشاء الكائنات بطرق مختلفة. اقرأ رقماً من المدخلات يشير إلى عدد مرات زيادة العداد، ثم:
    • قم بإنشاء Counter باستخدام التهيئة المباشرة: Counter c1;
    • قم بإنشاء Counter آخر باستخدام تهيئة الأقواس (brace initialization): Counter c2{};
    • قم بزيادة c1 بعدد المرات المحددة في المدخلات
    • اطبع "<name>: <count>" لـ c1
    • اطبع "<name>: <count>" لـ c2

يجب أن يبدأ كلا العدادين من 0 بفضل المُنشئ الافتراضي الخاص بك، ولكن سيتم زيادة c1 فقط. يوضح هذا كيف تضمن المُنشئات الافتراضية أن يبدأ كل كائن في حالة صالحة ويمكن التنبؤ بها بغض النظر عن كيفية إنشائه.

قم بتضمين ملف الرأس الخاص بك في main.cpp باستخدام #include "Counter.h".

ورقة مرجعية

الـ default constructor (المُنشئ الافتراضي) هو مُنشئ يمكن استدعاؤه بدون أي وسائط (arguments). يقوم بتهيئة الكائن عندما لا يتم توفير قيم أولية.

class Player {
    int health;
    int score;
public:
    Player() {           // Default constructor
        health = 100;
        score = 0;
    }
};

Player p1;               // Calls default constructor
Player p2{};             // Also calls default constructor

إذا لم تقم بتعريف أي مُنشئ، يقوم المترجم (compiler) بإنشاء مُنشئ افتراضي ضمني. ومع ذلك، بمجرد تعريف أي مُنشئ (مثل المُنشئ ذو المعاملات - parameterized constructor)، لن يقوم المترجم بإنشاء مُنشئ افتراضي تلقائياً.

class Enemy {
    int damage;
public:
    Enemy(int d) : damage(d) {}  // Parameterized constructor only
};

Enemy e1(10);    // Works
Enemy e2;        // Error! No default constructor

يمكنك طلب المُنشئ الافتراضي الذي يولده المترجم صراحةً باستخدام = default:

class Item {
    int id;
public:
    Item() = default;           // Compiler generates default constructor
    Item(int i) : id(i) {}
};

تعد المُنشئات الافتراضية ضرورية لإنشاء مصفوفات من الكائنات وللأصناف (classes) المستخدمة في الحاويات مثل std::vector.

جرّب بنفسك

#include <iostream>
#include "Counter.h"

using namespace std;

int main() {
    // اقرأ عدد مرات الزيادة
    int n;
    cin >> n;

    // TODO: أنشئ Counter باستخدام التهيئة المباشرة: Counter c1;

    // TODO: أنشئ Counter آخر باستخدام تهيئة الأقواس: Counter c2{};

    // TODO: قم بزيادة c1 بعدد المرات المحدد بواسطة n

    // TODO: اطبع "<name>: <count>" لـ c1

    // TODO: اطبع "<name>: <count>" لـ c2

    return 0;
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming