هو تابع عضو في الصف يحمل املواصفات التالية : له نفس اسم الصف . يستدعى ضمنيا عند إنشاء الغرض . ليس له قيمة.
Download ReportTranscript هو تابع عضو في الصف يحمل املواصفات التالية : له نفس اسم الصف . يستدعى ضمنيا عند إنشاء الغرض . ليس له قيمة.
Slide 1
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 2
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 3
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 4
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 5
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 6
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 7
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 8
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 9
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 10
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 11
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 12
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 13
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 14
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 15
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 16
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 17
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 18
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 19
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 20
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 21
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 22
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 23
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 24
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 25
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 26
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 27
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 28
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 29
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 30
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 31
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 32
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 33
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 34
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 35
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 36
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 37
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 38
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 39
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 40
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 41
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 42
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 43
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 44
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 45
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 46
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 47
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 2
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 3
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 4
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 5
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 6
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 7
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 8
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 9
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 10
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 11
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 12
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 13
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 14
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 15
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 16
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 17
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 18
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 19
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 20
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 21
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 22
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 23
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 24
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 25
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 26
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 27
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 28
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 29
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 30
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 31
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 32
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 33
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 34
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 35
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 36
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 37
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 38
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 39
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 40
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 41
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 42
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 43
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 44
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 45
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 46
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري
Slide 47
هو تابع عضو في الصف يحمل املواصفات التالية :
له نفس اسم الصف .
يستدعى ضمنيا عند إنشاء الغرض .
ليس له قيمة معادة أي ليس له نمط إرجاع .
يمكن أن نقوم بإجراء Overloadingله .
يتم التصريح عنه في قسم الـ publicوإن تم التصريح عنه في قسم الـ privateفإنه
سيحصل مشكلة عند إنشاء غرض ما .
في الباني نقوم بإعطاء قيمة ابتدائية للمتحوالت .
يوجد باني افتراض ي default constructor without parametersمبني
ضمنيا في اللغة وال يقوم بأي ش ي فإذا كنا نريد تعديله فإننا نعيد كتابته من جديد.
يمكن عمل overloadingله وبالتالي يمكن إنشاء أكثر من باني وكل باني يأخذ
عدد معين من الـ . parameters
يتم استدعاء الباني ضمنيا عند إنشاء غرض أو عند إجراء عملية newأي يمكننا
القول بأنه يتم استدعاء الباني ضمنيا عند إنشاء غرض سواء ستاتيكيا أو ديناميكيا.
هنا يتم استدعاء الباني االفتراض ي املوجود في اللغة الذي ال يأخذ متحوالت.
هنا يتم استدعاء الباني الذي تم كتابته داخل الصف .
هذه طريقة أخرى في إسناد القيم إلى متحوالت الصف ضمن الباني وتدعى هذه
الطريقة بـ . member initialization lists
عندما نضع القوسين )( عند بناء الغرض فإننا هنا نطلب استدعاء الـ default
. constructor
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن النوع األول وهو الباني االفتراض ي واآلن سوف نتكلم عن الباني
الناسخ.
إذا لم يعرف هذين البانيين من قبل املبرمج فإنها تكون معرفة تلقائيا عند تعريف
الصف.
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الحظ أن الباني الناسخ له معامل دخل واحد يمرر بالعنوان الثابت حتى ال يتم التعديل
عليه والهدف من الباني الناسخ هو إنشاء غرض مماثل للغرض الذي يتم تمريره للباني
الناسخ.
إذا مهمة الباني الناسخ هو إنشاء نسخة طبق األصل لغرض ما يتم تمرير هذا األخير
بالعنوان الثابت كي ال يتغير .
يوجد باني ناسخ افتراض ي ،ولكن إعادة كتابة الباني الناسخ تعطينا قدرة أكبر على التحكم
في البرنامج .
جرب نفس املثال السابق ولكن بدون كتابة الباني
االفتراض ي الذي ال يحوي معامالت ..ماذا يحدث ؟
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
الباني الناسخ يتم استدعاءه في إحدى الحاالت الثالث التالية :
عندما يتم تمرير objectلتهيئة objectآخر وهذا كما في األمثلة السابقة .
عندما يتم تمرير objectبالقيمة ،هنا يتم أخذ نسخة من الغرض للتعامل معه داخل التابع كي
ال تتعدل النسخة األساسية )تذكر التمرير بالقيمة .(by value
عندما يتم إرجاع غرض من تابع ،هنا أيضا يتم أخذ نسخة من الغرض من داخل التابع ليتم رده
للنطاق الخارجي .
إن استخدام إشارة اإلسناد بين األغراض تؤدي إلى استدعاء الباني الناسخ املوجود في
النظام دوما .
يتم نسخ جميع قيم متحوالت الغرض املوجود في القسم األيمن من عملية اإلسناد إلى
متحوالت الغرض املوجود في القسم األيسر من عملية اإلسناد على التتالي .
ال ينصح باستخدام عملية اإلسناد لنسخ قيم غرض إلى غرض آخر وخاصة عندما يحوي
الغرض على مؤشرات .سنتكلم عن هذا األمر بعد قليل .
إن جميع ما تكلمنا عنه سابقا يندرج تحت الـ . Shallow copy
الباني الناسخ في لغة الـ C++يستخدم الـ . Shallow copy
الـ Assignment operatorأيضا يستخدم الـ . Shallow copy
في الـ Shallow Copyفي حال كان الصف يحوي على مؤشرات فإن املؤشر املوجود في
الغرض األساس ي واملؤشر املوجود في النسخة يصبحان يشيران إلى نفس املكان في الذاكرة ،
ففي حال تم تحرير مكان الذاكرة هذا من قبل أحد األغراض فإن هذا يسبب مشاكل كبيرة
بالنسبة للغرض اآلخر ،إذا ما الحل ؟
إذا كان الصف يحوي على مؤشرات فإنه يجب علينا كتابة Deep Copy
.Constructor
في Deep Copy Constructorنقوم بإنشاء مواقع جديدة في الذاكرة ونجعل
املؤشرات تشير إليها وبعدها ننقل القيم املوجودة في الغرض األصل إلى النسخة الجديدة.
هذه األمور يجب الحذر منها وهي التي تتعلق بالحجز الديناميكي في الذاكرة عن طريق
التعليمتان newو deleteواللتان تتعلقان باملؤشرات .
نقوم بكتابة Body of Deep Copy Constructorفي الباني الناسخ الذي تكلمنا
كل صف له على األقل بانيان موجودين ضمنيا:
الباني التلقائي default constructorوهو بالشكل ) (Circle
الباني الناسخ copy constructorوهو بالشكل )Circle (const Circle & c
تكلمنا سابقا عن البانيين السابقين .
ولكن يوجد أيضا ما يسمى بالهادم والذي يعمل عكس عمل الباني فينبغي أن تكون
مهمته تحرير الذاكرة املحجوزة بشكل ديناميكي.
له نفس اسم الصف .
نميزه عن الباني بأنه مسبوق باإلشارة ~ أي يكون }~Class_name{…..
ال يوجد وسطاء دخل وال يوجد . return type
ال يمكن عمل overloadingله .
يستدعى تلقائيا عند موت الغرض أي عند انتهاء فترة حياته .
يوجد هادم موجود مسبقا في اللغة ولكن يمكن أيضا كتابته بأنفسنا مما يؤمن قدرة
أكبر على التحكم في ذاكرة البرنامج وخاصة أثناء التعامل مع املؤشرات .
آخر غرض تم إنشاءه هو أول غرض يتم حذفه ولكن يتم ذلك وفق قيود معينة .
نهتم أوال بإنشاء األغراض العامة وفقا لترتيب ورودها .
تذكر أنه بعد الخروج من local scopeيتم تدمير الغرض وبالتالي يتم استدعاء
الهادم تلقائيا .
بالنسبة لألغراض التي صرح على أنها staticتذكر أنها تنشأ مرة واحدة فقط وأنه
يتم تدميرها بعد االنتهاء من الـ mainأو الوصول إلى . exit
بشكل عام يتم استدعاء الهادم وفق ترتيب معاكس الستدعاء الباني .
أحيانا قد نضطر إلنشاء غرض ثابت مثال
). Ratio r (22,7
الغرض الثابت ال يمكن تعديله .
يتم التصريح عنه بالشكل التالي const class_name object_name( ..) :
إن أي محاولة لتعديل الغرض الثابت يعطي Compiler Errorحتى إن لم تكن
الـ data membersقد تم التصريح على أنها . const
الغرض الثابت ال يستطيع استدعاء الـ methodفي صف ؟ حيث يظهر لدينا
. Compiler Error
عند تعريف غرض على أنه ثابت فإنه يحظر
علينا استخدام توابع الصف .إذا ما الحل ؟
قم بالتصريح عن التوابع األعضاء في الصف
على أنها ثوابت أيضا .
تذكر أن األغراض الثابتة ال تستطيع التعامل
إال مع التوابع األعضاء الثابتة.
ال يمكن تغيير قيم الـ data members
ضمن .const method
تذكر القواعد التالية :
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض الغير ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
األغراض الثابتة ال تستطيع استدعاء توابع أعضاء غير ثابتة .
األغراض ثابتة تستطيع استدعاء توابع أعضاء ثابتة .
إذا كان لدينا صف يحوي على data memberتم التصريح عنه على أنه
. const
نحن نعلم أنه ال يمكن إعطاء قيم ابتدائية للـ data memberمباشرة عند
تعريفها في الصف ،بل كنا نقوم بعملية التهيئة في الباني .
ولكن هنا ستعتبر عملية التهيئة في الباني كأنها تعديل على الـ const data
memberوهذا سيؤدي بدوره إلى . Compiler Error
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
إذا ما هو املكان املناسب كي نقوم بإعطاء const data membersقيمها ؟؟
ما رأيك لو كان الحل بأن نصرح عن الباني على أنه constكما فعلنا في التوابع
األعضاء في املثال السابق ؟
هذا خاطئ تذكر اآلتي :إن البواني والهوادم ال يمكن أن تكون . const
إذا ما الحل ؟
الحل هو استخدام Member initialization listsوهي الطريقة الثانية في كتابة الباني.
وظيفة كتابة صف للتعبير عن العدد الكسري
وتضمين العمليات التالية :
جمع وطرح عددين كسريين
ضرب وقسمة عددين كسريين
مقارنة عددين كسريين
طباعة العدد الكسري