الدرس 5 من 10
القيمة والمرجع
- 12 دقيقة
- 5 فحوص
- 3 تلميحات
- إلى المطلوب
هدف الدرس
تعديل الأصل بالمرجع وتمرير النصّ دون نسخه
الشرح
حين تستدعي دالة في C++ تأخذ الدالة نسخة من كل قيمة تمرّرها إليها، فـ void heal(int hp) { hp += 10; } تزيد نسختها هي، ويبقى المتغيّر الذي مرّرته كما كان. وهذا آمن، لكنه ليس ما تريده حين تكون مهمّة الدالة أن تغيّر المتغيّر نفسه.
وإذا كتبت & بعد النوع صار المعامل مرجعًا (reference)، أي اسمًا آخر للمتغيّر الذي مرّرته نفسه وليس نسخة منه، فـ void heal(int& hp) { hp += 10; } تغيّر المتغيّر الذي مُرِّر إليها. ويبقى الاستدعاء كما هو heal(playerHp);، فالفرق كلّه في توقيع الدالة (signature)، أي سطرها الأول. والمرجع يحتاج إلى متغيّر يشير إليه، لذلك لا يقبل المترجم heal(50)، إذ لا يوجد متغيّر يمكن تغييره.
ونسخ عدد لا يكلّف شيئًا يُذكر، أما نسخ نصّ طويل أو قائمة كبيرة فمكلف، لذلك تمرّر const std::string& name الأصل بلا نسخ، وconst تَعِد بأنّ الدالة لن تغيّره، ويرفض المترجم أي محاولة لتعديله. وهذه هي الطريقة المعتادة لتمرير النصوص والكائنات الكبيرة التي تُقرأ فقط، وتراها في Unreal في كل مكان بالشكل const FString&.
المطلوب
الدوال الثلاث مكتوبة لكنها لا تعمل، لأنّ كل واحدة منها تعدّل نسخة. شغّل البرنامج وانظر إلى النتيجة، ثم أصلح تواقيعها بحيث تبادل swapValues(a, b) قيمتي المتغيّرين نفسيهما، وتزيد addBonus(score, bonus) النقاط نفسها وتتجاهل المكافأة السالبة، وتضع addTag(name, tag) الوسم قبل الاسم نفسه بالشكل [VIP] ليان وتقرأ tag مرجعًا ثابتًا const std::string&.
الفحوص
5 فحوص- الدالة swapValues تبادل المتغيّرين أنفسهما
- الدالة addBonus تزيد النقاط نفسها
- الدالة addBonus تتجاهل المكافأة السالبة
- الدالة addTag تضع الوسم قبل الاسم نفسه
- الدالة addTag تقرأ tag بـ const std::string& بلا نسخ