"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > متى يؤدي إرجاع كائن حسب القيمة إلى تشغيل منشئ الحركة؟

متى يؤدي إرجاع كائن حسب القيمة إلى تشغيل منشئ الحركة؟

تم النشر بتاريخ 2024-11-16
تصفح:618

When Does Returning an Object by Value Trigger a Move Constructor?

إرجاع كائن من فئة من دالة حسب القيمة

ضع في اعتبارك الحالة التي تقوم فيها بإرجاع كائن من فئة من دالة بواسطة قيمة. في هذا السيناريو، يعتبر الكائن الذي تم إرجاعه عادةً قيمة، مما يعني أنه يحتوي على اسم وعنوان في الذاكرة. ومع ذلك، يمكن أن تؤدي ظروف معينة إلى معاملة الكائن الذي تم إرجاعه كقيمة r، وهو كائن مؤقت بدون اسم أو عنوان.

تحدد قاعدة النقل الضمني

C قاعدة النقل الضمنية التي قد تنطبق عند إرجاع كائن حسب القيمة. تنص هذه القاعدة على أنه إذا تم استيفاء الشروط التالية:

  • التعبير الذي تم إرجاعه هو قيمة x (تعبير يشير إلى كائن مؤقت ليس قيمة l).
  • فئة يحتوي الكائن الذي تم إرجاعه على مُنشئ الحركة.
  • يمكن الوصول إلى مُنشئ الحركة.
في مثل هذه الحالات، سيتم استدعاء مُنشئ النقل بدلاً من مُنشئ النسخ. يهدف هذا السلوك إلى تحسين الأداء عن طريق تجنب النسخ غير الضروري.

المثال 1

في هذا المثال، الكائن الذي تم إرجاعه i هو lvalue، لذا فإن اختبار مُنشئ النسخ ( يتم استدعاء اختبار const& z):

class test {
public:
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(const test& z) { printf("test(const test&z)\n"); }
};
test Some_thing() {
    test i;
    return i;
}
الإخراج:

اختبار () test(const test&z)
test()
test(const test&z)

مثال 2

ومع ذلك، في المثال التالي، يتم التعامل مع الكائن الذي تم إرجاعه i كقيمة x، واختبار مُنشئ النقل( test&&s) لأن الكائن مؤقت ومنشئ النقل قابل للتطبيق:

class test {
public:
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(test&& s) { printf("test(test&& s)\n"); }
};
test Some_thing() {
    test i;
    return i;
}
الإخراج:

اختبار () test(test&& s)
test()
test(const test&z)

مثال 3إذا لم يتم توفير مُنشئ النقل أو تم حذفه بشكل صريح، فلا يمكن تطبيق قاعدة النقل الضمنية، و سيفشل البرنامج في التجميع:

class test { عام: test(test&&z) = حذف; اختبار(int y) { printf("test(int y)\n"); } test() { printf("test()\n"); } test(const test& z) { printf("test(const test&z)\n"); } }; اختبار Some_thing() { اختبار أنا؛ العودة أنا؛
class test {
public:
    test(test&& z) = delete;
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(const test& z) { printf("test(const test&z)\n"); }
};
test Some_thing() {
    test i;
    return i;
}
الاستنتاج

عند إرجاع كائن حسب القيمة، قد يتم تطبيق قاعدة النقل الضمنية في ظل ظروف محددة، مما يؤدي إلى استدعاء مُنشئ النقل. يعد فهم هذا السلوك أمرًا بالغ الأهمية لتحسين التعليمات البرمجية ومنع أخطاء الترجمة.

أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3