شرح لـ Static Class Member و Static Member Function
المقدمة
في لغة C++، يقدم "static class members" و"static member functions" عناصر على مستوى الفئة غير مرتبطة بالكائنات الفردية للفئة.
#include <iostream> #include <string> using namespace std; void f() { static int x = 0; x++; cout << x << endl; } int main() { f(); f(); return 0; }
يعرّف برنامج C++ هذا الدالة f() التي تزيد متغيرًا صحيحًا ثابتًا x في كل مرة يتم استدعاؤها، ثم تطبع قيمة x إلى المخرجات القياسية. الدالة main() تستدعي f() مرتين.
إليك ما يفعله البرنامج:
- تم تعريف الدالة f(). أنه يحتوي على متغير static x تمت تهيئته إلى 0.
- في كل مرة يتم استدعاء الدالة f()، فإنها تزيد x بمقدار 1 وتطبع القيمة الجديدة لـ x.
- في الدالة main()، يتم استدعاء f() مرتين.
- عندما يتم استدعاء f() للمرة الأولى، تتم زيادة x من 0 إلى 1، ويتم طباعة 1.
- عندما يتم استدعاء f() للمرة الثانية، تتم زيادة x من 1 إلى 2، ويتم طباعة 2.
ولذلك، عند تشغيل البرنامج، يجب أن تكون المخرجات كالتالي:
1 2
إليك ما يفعله static في هذا السياق:
- الحفاظ على القيمة بين استدعاءات الدوال: عندما يتم تعريف متغير على أنه static داخل دالة، فإن قيمته تستمر بين استدعاءات الدوال. وهذا يعني أن المتغير يحتفظ بقيمته حتى بعد خروج الدالة f(). في المثال، يحتفظ المتغير x بقيمته بين استدعاءات f().
- التهيئة: تتم تهيئة المتغيرات الثابتة Static مرة واحدة فقط، في بداية تنفيذ البرنامج. في هذه الحالة، تتم تهيئة المتغير Static x إلى 0 في المرة الأولى التي يتم فيها استدعاء الدالة f(). لا تؤدي الاستدعاءات اللاحقة إلى f() إلى إعادة تهيئة x.
- مدة التخزين: المتغيرات الثابتة Static لها "مدة تخزين ثابتة"، مما يعني أنها مخصصة للذاكرة طوال مدة تنفيذ البرنامج. يتم تخصيص هذه الذاكرة في جزء البيانات من البرنامج.
- النطاق: يقتصر نطاق المتغير الثابت static المعلن داخل الدالة على تلك الدالة. ولا يمكن الوصول إليه من خارج الدالة. في هذا المثال، لا يمكن الوصول إلى x إلا من خلال الدالة f().
Static Class Member
#include <iostream> #include <cstring> #include <string> using namespace std; //define how many objects are created class Student { static int count; char name[20]; int first, second, final, total, ID; public: Student() //constructor { strcpy(name, "No name"); ID = 0; first = second = final = 0; count++; cout << "Numbers of students constructed: " << count << endl; } }; //end of class int Student::count = 0; int main() { cout << "\nConstruct 2 objects\n"; Student S1, S2; cout << "\nConstruct 3 objects\n"; Student St[3]; return 0; } //end of main
– تعريف الـ(Class): Student
- يعرف class Student بأسماء أعضاء البيانات الخاصة، first, second, final, total, وID
- تم تعريف متغير العدد على أنه static داخل الكلاس. وهذا يعني أنه مشترك بين جميع كانات Student class، وتستمر قيمتها عبر كائنات Student المتعددة.
أداة البناء Constructor:
- يحتوي الكلاس على أداة البناء الافتراضية Student() الذي يقوم بتهيئة أعضاء البيانات بالقيم الافتراضية.
- في constructor، يتم تهيئة name بـ"No name"، ويتم تهيئة ID بـ 0، ويتم تهيئة exam scores بـ 0.
- في كل مرة يتم إنشاء Student object، تتم زيادة متغير العدد، وتتم طباعة العدد الإجمالي للطلاب الذين تم إنشاؤهم.
تهيئة الـ Static Member:
- تتم تهيئة static member خارج تعريف class.
الدالة الرئيسة main:
- في الدالة main()، يتم إنشاء كائنين للـStudent (S1 وS2) باستخدام الـdefault constructor. يقوم البرنامج بطباعة عدد الطلاب الذين تم إنشاؤهم بعد إنشاء كل كائن.
- بعد ذلك، يتم إنشاء مصفوفة مكونة من ثلاثة كائنات للـStudent. مرة أخرى، يقوم البرنامج بطباعة عدد الطلاب الذين تم إنشاؤهم بعد إنشاء هذه المصفوفة.
المخرجات:
Construct 2 objects Numbers of students constructed: 1 Numbers of students constructed: 2 Construct 3 objects Numbers of students constructed: 3 Numbers of students constructed: 4 Numbers of students constructed: 5
يتم استخدام متغير الـ static member لتتبع العدد الإجمالي لكائنات الـStudent التي تم إنشاؤها. في كل مرة يتم فيها إنشاء كائن الطالب (أي عند استدعاء الـconstructor)، يزداد العدد. يسمح هذا للبرنامج بتتبع عدد كائنات الطالب التي تم إنشاء مثيل لها عبر تنفيذ البرنامج بأكمله.
Static Member Function
#include <iostream> #include <cstring> #include <string> using namespace std; class Student { static int count; char name[20]; int first, second, final, total, ID; public: static void print_count() { cout << "Students constructed: " << count << endl; } Student() //constructor { strcpy(name, "No name"); ID = 0; first = second = final = 0; count++; print_count(); } }; //end of class int Student::count = 0; int main() { Student::print_count(); cout << "\nConstruct 2 objects\n"; Student S1, S2; cout << "\nConstruct 3 objects\n"; Student St[3]; return 0; } //end of main
في هذا البرنامج الذي تم تحديثه، تمت إضافة وظيفة العضو (static ) print_count() إلى فئة الطالب. إليك ما تفعله الكلمة الأساسية static في هذا السياق:
- Static Member Function: تم تعريف دالة العضو print_count() على أنها static. وهذا يعني أنه ينتمي إلى الفئة نفسها، وليس إلى المثيلات الفردية (الكائنات) للفئة. لا تتمتع دوال الأعضاء الـstatic بإمكانية الوصول إلى متغيرات أو دوال الأعضاء غير الـstatic مباشرة لأنها غير مرتبطة بأي كائن معين.
- الوصول إلى متغيرات الأعضاء الـStatic: داخل دالة العضو الثابت print_count()، يتم الوصول إلى عدد متغيرات الأعضاء الــstatic مباشرة. وبما أن العد هو أيضًا static، فيمكن الوصول إليه دون الحاجة إلى مثيل للفئة.
- الوصول إلى دالة العضو الـStatic: يمكن استدعاء دوال العضو الـStatic باستخدام اسم الكلاس متبوعًا بعامل تحليل النطاق (::). على سبيل المثال، يستدعي Student::print_count() الدالة print_count() الخاصة بكلاس Student .
- الاستخدام: في الدالة main()، يتم استدعاء Student::print_count() قبل إنشاء أي كائنات Student. يوضح هذا أنه يمكن استدعاء دوال الأعضاء الـstatic دون الحاجة إلى إنشاء مثيل للكائن.
- التهيئة والزيادة: داخل Student constructor، تتم زيادة متغير العدد في كل مرة يتم فيها إنشاء كائن طالب جديد. يتم استدعاء الدالة print_count() داخل المنشئ لعرض العدد المحدث بعد كل إنشاء للكائن.
يوضح هذا البرنامج استخدام دالة عضو static للوصول إلى متغير عضو static وتوفير الدوال المرتبطة بالفئة نفسها، بدلاً من الكائنات الفردية للفئة.