C ++ نسخ مُنشئ ، مؤقتة ونسخ الدلالات
سؤال
لهذا البرنامج
#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
.
راجع للشغل ، يبدو المثال على ويكي يشبه إلى حد بعيد الرمز الخاص بك.