سؤال

لهذا البرنامج

#include <iostream>
using std::cout;

struct C 
{
    C() { cout << "Default C called!\n"; }
    C(const C &rhs) { cout << "CC called!\n"; }
};

const C f()
{
    cout << "Entered f()!\n";
    return C();
}

int main()
{
    C a = f();
    C b = a;

    return 0;
}

الإخراج الذي أحصل عليه هو:

Entered f()!
Default C called!
CC called!

حيث f() يعود بالقيمة ، يجب أن يعيد مؤقتًا. مثل T a = x; هو T a(x);, ، ألا يدعو مُنشئ النسخ لبناء a, ، مع تمرير المؤقتة كحجة؟

هل كانت مفيدة؟

المحلول

حيث f() يعود بالقيمة ، يجب أن يعيد مؤقتًا. مثل T a = x; هو T a(x);, ، ألا يدعو مُنشئ النسخ لبناء a, ، مع تمرير المؤقتة كحجة؟

ابحث عن تحسين قيمة الإرجاع. يتم تشغيل هذا بشكل افتراضي. إذا كنت على Windows باستخدام MSVC 2005+ يمكنك استخدامها /Od لإيقاف هذا والحصول على النتيجة المرجوة (أو -fno-elide-constructors على دول مجلس التعاون الخليجي). أيضا ، لتصبح MSVC انظر هذه مقالة - سلعة.

12.8 نسخ كائنات فئة

15 عندما يتم استيفاء معايير معينة ، يُسمح للتنفيذ بحذف نسخ إنشاء كائن فئة ، حتى لو كان لمؤسسة النسخ و/أو المدمرة للكائن آثار جانبية. في مثل هذه الحالات ، يعامل التنفيذ مصدر وهدف عملية النسخ المحذوفة كطريقتين مختلفتين للإشارة إلى نفس الكائن ، ويحدث تدمير هذا الكائن في وقت لاحق من الأوقات التي كان قد تم فيها تدمير الكائنين بدونها بدون التحسين.

في بيان الإرجاع في وظيفة مع نوع إرجاع الفصل ،عندما يكون التعبير هو اسم كائن أوتوماتي غير متطابق مع نفس النوع المؤهل CV كنوع إرجاع الوظيفة ، يمكن حذف عملية النسخ عن طريق بناء الكائن التلقائي مباشرة في قيمة إرجاع الوظيفة-في التعبير عن الرمي ، عندما يكون المعامل هو اسم كائن تلقائي غير متطابق ، يمكن حذف عملية النسخ من المعامل إلى كائن الاستثناء (15.1) عن طريق بناء الكائن التلقائي مباشرة في كائن الاستثناء

-عندما يتم نسخ كائن فئة مؤقتة لم يكن مرتبطًا بمرجع (12.2) ينسخ

-عندما يعلن استثناء الاستثناء لمعالج الاستثناء (الفقرة 15) كائن من نفس النوع (باستثناء تأهيل CV) ككائن استثناء (15.1) ، يمكن حذف عملية النسخ عن طريق التعامل الاسم المستعار لكائن الاستثناء إذا لم يتغير معنى البرنامج باستثناء تنفيذ المُنشئين والمدمرين للكائن المعلن عن طريق الاستثناء.

ملاحظة: التركيز الألغام

نصائح أخرى

هذا مثال على تحسين قيمة الإرجاع (RVO) الميزات التي يدعمها المترجم الخاص بك.

منشئ نسخة قد لا يتم استدعاؤها عند العودة بالقيمة.

يستخدم -fno-elide-constructors خيار على GCC لإيقاف هذه الميزة.

أعتقد أنه يسمى تحسين قيمة الإرجاع.

أفترض متى f() عائدات C الكائن يتم تخصيص الكائن في مساحة مكدس طريقة الاتصال ، لذلك لا توجد نسخة مطلوبة لتهيئة C a. وهذا هو الخاص بك default C called.

C b = a

هذا يسبب منشئ النسخ الخاص بك CC called.

راجع للشغل ، يبدو المثال على ويكي يشبه إلى حد بعيد الرمز الخاص بك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top