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

المنشئ ذو المعاملات

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

يقبل المنشئ ذو البارامترات (parameterized constructor) وسائط تتيح لك تهيئة كائن بقيم محددة عند وقت الإنشاء. فبدلاً من الاعتماد على القيم الافتراضية، يمكنك تخصيص الحالة الأولية لكل كائن.

class Player {
    std::string name;
    int health;
    int level;
public:
    Player(std::string n, int h, int lvl) {
        name = n;
        health = h;
        level = lvl;
    }
};

Player hero("Archer", 100, 5);
Player mage("Wizard", 80, 7);

يمكنك تعريف عدة منشئات ذات معاملات (parameterized constructors) بقوائم معاملات مختلفة. يُسمى هذا تحميل المنشئ الزائد (constructor overloading)، ويقوم المترجم (compiler) باختيار المنشئ المناسب بناءً على الوسائط (arguments) التي تقدمها.

class Rectangle {
    int width, height;
public:
    Rectangle(int side) {          // مربع
        width = height = side;
    }
    
    Rectangle(int w, int h) {      // مستطيل
        width = w;
        height = h;
    }
};

Rectangle square(10);        // يستدعي المنشئ الأول
Rectangle rect(10, 20);      // يستدعي المنشئ الثاني

يمكن أن تمتلك المعاملات قيمًا افتراضية، مما يجعل بعض الوسائط اختيارية. وهذا يقلل من الحاجة إلى منشئات متعددة محملة بشكل زائد.

class Enemy {
    std::string type;
    int damage;
public:
    Enemy(std::string t, int d = 10) : type(t), damage(d) {}
};

Enemy goblin("Goblin");       // القيمة الافتراضية للضرر هي 10
Enemy dragon("Dragon", 50);   // تم تعيين الضرر إلى 50

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

challenge icon

التحدي

سهل

لنقم ببناء نظام مخزون منتجات يوضح كيف تسمح لك المُنشئات ذات المعاملات (parameterized constructors) بإنشاء كائنات بقيم أولية محددة، وكيف يوفر تعدد أشكال المُنشئ (constructor overloading) المرونة في إنشاء الكائنات.

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

  • Product.h: قم بتعريف فئة Product التي تمثل العناصر في المخزون. يجب أن تحتوي الفئة الخاصة بك على:
    • سمات خاصة (Private attributes) لـ name (سلسلة نصية)، و price (عدد عشري double)، و quantity (عدد صحيح integer)
    • مُنشئ (constructor) يأخذ جميع المعاملات الثلاثة (الاسم، السعر، الكمية) لتهيئة المنتج بالكامل
    • مُنشئ يأخذ الاسم والسعر فقط، مع جعل الكمية الافتراضية 1
    • مُنشئ يأخذ الاسم فقط، مع جعل السعر الافتراضي 0.0 والكمية الافتراضية 0
    • دالة display() تقوم بطباعة معلومات المنتج بالتنسيق التالي: "<name>: "<name>: $<price> (x<quantity>)"lt;price> (x<quantity>)"
    • دالة getTotalValue() تعيد قيمة السعر مضروباً في الكمية
  • main.cpp: قم بتوضيح المُنشئات الثلاثة من خلال قراءة المدخلات وإنشاء المنتجات بطرق مختلفة. اقرأ ما يلي من المدخلات:
    • السطر الأول: اسم المنتج، السعر، والكمية (مفصولة بمسافات)
    • السطر الثاني: اسم المنتج والسعر (مفصولين بمسافات)
    • السطر الثالث: اسم المنتج فقط
    قم بإنشاء ثلاثة كائنات Product باستخدام المُنشئ المناسب لكل مدخل، واستدعِ display() لكل منها، ثم اطبع القيمة الإجمالية لجميع المنتجات الثلاثة معاً بالتنسيق التالي: "Total inventory value: "Total inventory value: $<value>"lt;value>"

بالنسبة لمخرجات السعر، قم بالعرض بمنزلة عشرية واحدة. على سبيل المثال، إذا قمت بإنشاء منتج "Laptop" بسعر 999.99 وكمية 5، يجب أن يظهر العرض "Laptop: $999.99 (x5)".

قم بتضمين ملف الرأس (header file) في main.cpp باستخدام #include "Product.h".

ورقة مرجعية

يقبل المُنشئ ذو المعاملات (parameterized constructor) وسائط لتهيئة كائن بقيم محددة عند وقت الإنشاء:

class Player {
    std::string name;
    int health;
    int level;
public:
    Player(std::string n, int h, int lvl) {
        name = n;
        health = h;
        level = lvl;
    }
};

Player hero("Archer", 100, 5);

يسمح تحميل المُنشئ الزائد (Constructor overloading) بوجود عدة مُنشئات بقوائم معاملات مختلفة:

class Rectangle {
    int width, height;
public:
    Rectangle(int side) {          // مربع
        width = height = side;
    }
    
    Rectangle(int w, int h) {      // مستطيل
        width = w;
        height = h;
    }
};

Rectangle square(10);        // يستدعي المُنشئ الأول
Rectangle rect(10, 20);      // يستدعي المُنشئ الثاني

تجعل قيم المعاملات الافتراضية الوسائط اختيارية:

class Enemy {
    std::string type;
    int damage;
public:
    Enemy(std::string t, int d = 10) : type(t), damage(d) {}
};

Enemy goblin("Goblin");       // damage تكون قيمتها الافتراضية 10
Enemy dragon("Dragon", 50);   // damage تم تعيينها إلى 50

بمجرد تعريف مُنشئ ذو معاملات، لن يقوم المترجم (compiler) بإنشاء مُنشئ افتراضي تلقائيًا بعد الآن.

جرّب بنفسك

#include <iostream>
#include <iomanip>
#include <string>
#include "Product.h"

using namespace std;

int main() {
    // قراءة المنتج الأول: الاسم، والسعر، والكمية
    string name1;
    double price1;
    int quantity1;
    cin >> name1 >> price1 >> quantity1;
    
    // قراءة المنتج الثاني: الاسم والسعر
    string name2;
    double price2;
    cin >> name2 >> price2;
    
    // قراءة المنتج الثالث: الاسم فقط
    string name3;
    cin >> name3;
    
    // TODO: إنشاء ثلاثة كائنات Product باستخدام المنشئ (constructor) المناسب لكل منها
    
    // TODO: استدعاء ()display لكل منتج
    
    // TODO: حساب وطباعة القيمة الإجمالية للمخزون
    // التنسيق: "Total inventory value: $<value>"
    // استخدم fixed و setprecision(1) لمنزلة عشرية واحدة
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming