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

أعضاء الـ Instance مقابل الـ Static

جزء من قسم البرمجة كائنية التوجه في رحلة C++ على Coddy. الدرس 27 من 104.

حتى الآن، ينتمي كل متغير عضو أنشأته إلى كائن محدد. عند إنشاء كائنَي Player، يمتلك كلٌّ منهما name وhealth خاصَّين به. تُسمّى هذه أعضاء النسخة - وهي موجودة بشكل منفصل لكل نسخة من الفئة.

ولكن ماذا لو احتجت إلى بيانات مشتركة بين جميع الكائنات؟ على سبيل المثال، تتبُّع عدد اللاعبين الموجودين إجمالًا.

هنا يأتي دور الأعضاء الساكنة. ينتمي العضو الساكن إلى الفئة نفسها، وليس إلى أي كائن معيّن.

class Player {
    std::string name;           // عضو مثيل - كل لاعب لديه خاصته
    int health;                 // عضو مثيل
    
    static int playerCount;     // عضو ثابت - مشترك بين جميع اللاعبين
    
public:
    Player(std::string n) : name(n), health(100) {
        playerCount++;          // زيادة عند إنشاء أي لاعب
    }
    
    ~Player() {
        playerCount--;          // إنقاص عند تدمير أي لاعب
    }
};

الفرق الأساسي: يتم الوصول إلى أعضاء النسخة من خلال كائن، بينما يمكن الوصول إلى الأعضاء الساكنة من خلال اسم class نفسه. فكّر في أعضاء النسخة على أنها «واحد لكل كائن»، وفي الأعضاء الساكنة على أنها «واحد لكل class».

أعضاء الكائنالأعضاء الساكنة
فريدة لكل كائنمشتركة بين جميع الكائنات
يتم created عند إنشاء الكائنتوجد قبل أن يتم created أي كائن
يتم الوصول إليها عبر الكائن: player.healthيتم الوصول إليها عبر class: Player::playerCount

تُعد الأعضاء الساكنة مفيدة لـ counters، وقيم التكوين، أو أي بيانات تنتمي منطقيًا إلى class بدلًا من الكائنات الفردية.

challenge icon

التحدي

سهل

لنَبْنِ نظامًا لمخزون المنتجات يتتبع تفاصيل كل منتج على حدة وإحصاءات المخزون الإجمالية باستخدام أعضاء المثيل والأعضاء الثابتة.

ستُنشئ ملفين لتنظيم التعليمات البرمجية:

  • Product.h: Define فئة Product تدير المنتجات الفردية وتتتبع أيضًا البيانات على مستوى المخزون بالكامل. يجب أن تحتوي فئتك على:
    • أعضاء مثيل: name (سلسلة نصية) وprice (double): فريدة لكل منتج
    • عضو ثابت totalProducts يحسب عدد المنتجات الموجودة حاليًا
    • عضو ثابت totalValue يتتبع السعر الإجمالي لجميع المنتجات
    • بانيًا يستقبل اسمًا وسعرًا، ويهيّئ أعضاء المثيل، ويحدّث كلا العدادين الثابتين (Increment العدد، وإضافة السعر إلى القيمة الإجمالية)
    • مدمّرًا يحدّث العدادين الثابتين عند إزالة منتج (Decrement العدد، وطرح السعر من القيمة الإجمالية)
    • أسلوب getInfo() يعيد سلسلة نصية بالتنسيق: "<name>: $<price>"
    • أسلوبًا ثابتًا getInventoryStats() يعيد سلسلة نصية: "Products: <count>, Total Value: $<value>"
  • main.cpp: وضّح كيفية مشاركة الأعضاء الثابتة بين جميع الكائنات، مع بقاء أعضاء المثيل فريدة. اقرأ اسمي منتجين وسعريهما من الإدخال (name1 وprice1 وname2 وprice2: كل منها في سطر منفصل)، ثم:
    • اطبع إحصاءات المخزون الأولية باستخدام اسم الفئة: Product::getInventoryStats()
    • أنشئ نطاقًا باستخدام الأقواس المعقوفة، وأنشئ بداخله Product بالاسم والسعر الأولين. اطبع معلوماته وإحصاءات المخزون الحالية.
    • After انتهاء النطاق (بعد تدمير المنتج الأول)، اطبع "After first scope:" متبوعًا بإحصاءات المخزون
    • أنشئ Product آخر بالاسم والسعر الثانيين. اطبع معلوماته وإحصاءات المخزون.
    • أنشئ Product ثالثًا بالاسم "Bonus" والسعر 5.00. اطبع إحصاءات المخزون النهائية.

تذكّر Define أعضاءك الثابتة خارج الفئة في ملف الترويسة (بعد تعريف الفئة). نسّق الأسعار بمنزلتين عشريتين باستخدام std::fixed وstd::setprecision(2) من <iomanip>.

Include ملف الترويسة في main.cpp باستخدام #include "Product.h".

جرّب بنفسك

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

using namespace std;

int main() {
    // اقرأ الإدخال
    string name1;
    double price1;
    string name2;
    double price2;
    
    getline(cin, name1);
    cin >> price1;
    cin.ignore();
    getline(cin, name2);
    cin >> price2;
    
    // TODO: اطبع إحصائيات المخزون الأولية باستخدام Product::getInventoryStats()
    
    // TODO: أنشئ كتلة نطاق بأقواس معقوفة
    // داخل الكتلة:
    //   - أنشئ Product باستخدام name1 و price1
    //   - اطبع معلوماته باستخدام getInfo()
    //   - اطبع إحصائيات المخزون الحالية
    
    // TODO: After the block ends, print "After first scope:"
    // ثم اطبع إحصائيات المخزون
    
    // TODO: أنشئ Product آخر باستخدام name2 و price2
    // اطبع معلوماته وإحصائيات المخزون
    
    // TODO: أنشئ Product ثالثًا بالاسم "Bonus" والسعر 5.00
    // اطبع إحصائيات المخزون النهائية
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C++ عبر الإنترنت