510 likes | 801 Views
C++ Programming. L10 . Classes(2). مراجعة Review :. مراجعة Review :. مراجعة Review :. مراجعة Review :. مراجعة Review :. مراجعة Review :. مراجعة Review :. الصفوف Classes ـ Constructor :. هو تابع عضو في الصف يحمل المواصفات التالية : له نفس اسم الصف .
E N D
C++ Programming L10 . Classes(2)
الصفوف Classes ـ Constructor : • هو تابع عضو في الصف يحمل المواصفات التالية : • له نفس اسم الصف . • يستدعى ضمنياً عند إنشاء الغرض . • ليس له قيمة معادة أي ليس له نمط إرجاع . • يمكن أن نقوم بإجراء Overloading له . • يتم التصريح عنه في قسم الـpublic وإن تم التصريح عنه في قسم الـprivate فإنه سيحصل مشكلة عند إنشاء غرض ما .
الصفوف Classes ـ Constructor : • في الباني نقوم بإعطاء قيمة ابتدائية للمتحولات . • يوجد باني افتراضي default constructor without parameters مبني ضمنياً في اللغة ولا يقوم بأي شي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد. • يمكن عمل overloading له وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ عدد معين من الـparameters . • يتم استدعاء الباني ضمنياً عند إنشاء غرض أو عند إجراء عملية new أي يمكننا القول بأنه يتم استدعاء الباني ضمنياً عند إنشاء غرض سواء ستاتيكياً أو ديناميكياً.
الصفوف Classes ـ Constructor : • هنا يتم استدعاء الباني الافتراضي الموجود في اللغة الذي لا يأخذ متحولات.
الصفوف Classes ـ Constructor : • هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
الصفوف Classes ـ Constructor : Compiler Error
الصفوف Classes ـ Constructor : • هذه طريقة أخرى في إسناد القيم إلى متحولات الصف ضمن الباني وتدعى هذه الطريقة بـmember initialization lists .
الصفوف Classes ـ Constructor : • عندما نضع القوسين () عند بناء الغرض فإننا هنا نطلب استدعاء الـdefault constructor .
الصفوف Classes ـ Copy Constructor : • كل صف له على الأقل بانيان موجودين ضمنياً: • الباني التلقائي default constructor وهو بالشكل Circle( ) • الباني الناسخ copy constructor وهو بالشكل Circle (const Circle & c) • تكلمنا سابقاً عن النوع الأول وهو الباني الافتراضي والآن سوف نتكلم عن الباني الناسخ. • إذا لم يعرف هذين البانيين من قبل المبرمج فإنها تكون معرفة تلقائياً عند تعريف الصف.
الصفوف Classes ـ Copy Constructor : • الباني الناسخ copy constructor وهو بالشكل Circle (const Circle & c) • لاحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى لا يتم التعديل عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني الناسخ. • إذاً مهمة الباني الناسخ هو إنشاء نسخة طبق الأصل لغرض ما يتم تمرير هذا الأخير بالعنوان الثابت كي لا يتغير . • يوجد باني ناسخ افتراضي ، ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم في البرنامج .
الصفوف Classes ـ Copy Constructor : • جرب نفس المثال السابق ولكن بدون كتابة الباني الافتراضي الذي لا يحوي معاملات .. ماذا يحدث ؟
الصفوف Classes ـ Copy Constructor : في هذا الـبرنامج تم إعادة كتابة الباني الناسخ من قبل المبرمج
الصفوف Classes ـ Copy Constructor : • الباني الناسخ copy constructor وهو بالشكل Circle (const Circle & c) • الباني الناسخ يتم استدعاءه في إحدى الحالات الثلاث التالية : • عندما يتم تمرير object لتهيئة object آخر وهذا كما في الأمثلة السابقة . • عندما يتم تمرير object بالقيمة ، هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي لا تتعدل النسخة الأساسية )تذكر التمرير بالقيمة (by value. • عندما يتم إرجاع غرض من تابع ، هنا أيضاً يتم أخذ نسخة من الغرض من داخل التابع ليتم رده للنطاق الخارجي .
الصفوف Classes ـ Copy Constructor : • الباني الناسخ copy constructor وهو بالشكل Circle (const Circle & c) • الباني الناسخ يتم استدعاءه في إحدى الحالات الثلاث التالية : • عندما يتم تمرير object لتهيئة object آخر وهذا كما في الأمثلة السابقة . • عندما يتم تمرير object بالقيمة ، هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي لا تتعدل النسخة الأساسية )تذكر التمرير بالقيمة (by value. • عندما يتم إرجاع غرض من تابع ، هنا أيضاً يتم أخذ نسخة من الغرض من داخل التابع ليتم رده للنطاق الخارجي .
الصفوف Classes ـ Copy Constructor : إن هذا المثال يشمل الحالات الثلاث السابقة
Copy Constructor (assignment =) : • إن استخدام إشارة الإسناد بين الأغراض تؤدي إلى استدعاء الباني الناسخ الموجود في النظام دوماً . • يتم نسخ جميع قيم متحولات الغرض الموجود في القسم الأيمن من عملية الإسناد إلى متحولات الغرض الموجود في القسم الأيسر من عملية الإسناد على التتالي . • لا ينصح باستخدام عملية الإسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي الغرض على مؤشرات . سنتكلم عن هذا الأمر بعد قليل .
Shallow Copy vs Deep Copy : • إن جميع ما تكلمنا عنه سابقاً يندرج تحت الـShallow copy . • الباني الناسخ في لغة الـC++ يستخدم الـShallow copy . • الـAssignment operator أيضاً يستخدم الـShallow copy . • في الـShallow Copy في حال كان الصف يحوي على مؤشرات فإن المؤشر الموجود في الغرض الأساسي والمؤشر الموجود في النسخة يصبحان يشيران إلى نفس المكان في الذاكرة ، ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد الأغراض فإن هذا يسبب مشاكل كبيرة بالنسبة للغرض الآخر ، إذاً ما الحل ؟ Write your Deep Copy Constructor
Shallow Copy vs Deep Copy : • إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy Constructor. • في Deep Copy Constructor نقوم بإنشاء مواقع جديدة في الذاكرة ونجعل المؤشرات تشير إليها وبعدها ننقل القيم الموجودة في الغرض الأصل إلى النسخة الجديدة. • هذه الأمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق التعليمتان new و delete واللتان تتعلقان بالمؤشرات . • نقوم بكتابة Body of Deep Copy Constructor في الباني الناسخ الذي تكلمنا عنه سابقاً والذي يحمل الترويسة التالية : Class_name (const Class_name & c)
Shallow Copy vs Deep Copy : Shallow Copy Constructor
Shallow Copy vs Deep Copy : Deep Copy Constructor
الصفوف Classes ـ Destructor : • كل صف له على الأقل بانيان موجودين ضمنياً: • الباني التلقائي default constructor وهو بالشكل Circle( ) • الباني الناسخ copy constructor وهو بالشكل Circle (const Circle & c) • تكلمنا سابقاً عن البانيين السابقين . • ولكن يوجد أيضاً ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون مهمته تحرير الذاكرة المحجوزة بشكل ديناميكي.
الصفوف Classes ـ Destructor : • له نفس اسم الصف . • نميزه عن الباني بأنه مسبوق بالإشارة ~ أي يكون ~Class_name{…..} • لا يوجد وسطاء دخل ولا يوجد return type . • لا يمكن عمل overloading له . • يستدعى تلقائياً عند موت الغرض أي عند انتهاء فترة حياته . • يوجد هادم موجود مسبقاً في اللغة ولكن يمكن أيضاً كتابته بأنفسنا مما يؤمن قدرة أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع المؤشرات .
الصفوف Classes ـ ملاحظات: • آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة . • نهتم أولاً بإنشاء الأغراض العامة وفقاً لترتيب ورودها . • تذكر أنه بعد الخروج من local scope يتم تدمير الغرض وبالتالي يتم استدعاء الهادم تلقائياً . • بالنسبة للأغراض التي صرح على أنها static تذكر أنها تنشأ مرة واحدة فقط وأنه يتم تدميرها بعد الانتهاء من الـmain أو الوصول إلى exit . • بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس لاستدعاء الباني .
الصفوف Classes ـ Const Object: • أحياناً قد نضطر لإنشاء غرض ثابت مثلاً Ratio r (22,7) . • الغرض الثابت لا يمكن تعديله . • يتم التصريح عنه بالشكل التالي :const class_nameobject_name( ..) • إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Error حتى إن لم تكن الـdata members قد تم التصريح على أنها const . • الغرض الثابت لا يستطيع استدعاء الـmethod في صف ؟ حيث يظهر لدينا Compiler Error .
الصفوف Classes ـ Const Object: • عند تعريف غرض على أنه ثابت فإنه يحظر علينا استخدام توابع الصف . إذاً ما الحل ؟ • قم بالتصريح عن التوابع الأعضاء في الصف على أنها ثوابت أيضاً . • تذكر أن الأغراض الثابتة لا تستطيع التعامل إلا مع التوابع الأعضاء الثابتة. • لا يمكن تغيير قيم الـdata members ضمن const method.
الصفوف Classes ـ Const Object: • تذكر القواعد التالية : • الأغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة . • الأغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة . • الأغراض الثابتة لا تستطيع استدعاء توابع أعضاء غير ثابتة . • الأغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
الصفوف Classes ـ Const Data Member: • إذا كان لدينا صف يحوي على data member تم التصريح عنه على أنه const . • نحن نعلم أنه لا يمكن إعطاء قيم ابتدائية للـdata member مباشرة عند تعريفها في الصف، بل كنا نقوم بعملية التهيئة في الباني . • ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـconst data member وهذا سيؤدي بدوره إلى Compiler Error . • إذاً ما هو المكان المناسب كي نقوم بإعطاء const data members قيمها ؟؟
الصفوف Classes ـ Const Data Member: • إذاً ما هو المكان المناسب كي نقوم بإعطاء const data members قيمها ؟؟ • ما رأيك لو كان الحل بأن نصرح عن الباني على أنه const كما فعلنا في التوابع الأعضاء في المثال السابق ؟ • هذا خاطئ تذكر الآتي : إن البوانيوالهوادم لا يمكن أن تكون const . • إذاً ما الحل ؟ • الحل هو استخدام Member initialization lists وهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسريوتضمين العمليات التالية :جمع وطرح عددين كسريينضرب وقسمة عددين كسريينمقارنة عددين كسريينطباعة العدد الكسري