سؤال

وهنا مقتطف من البند 56 من كتاب "++ C Gotchas":

<اقتباس فقرة>   

وانها ليست من غير المألوف أن نرى بسيط   تهيئة كائن Y مكتوبة   أي من ثلاث طرق مختلفة، كما لو   كانوا ما يعادلها.

Y a( 1066 ); 
Y b = Y(1066);
Y c = 1066;
<اقتباس فقرة>   

في الواقع، كل ثلاثة من هذه   ومن المحتمل أن يؤدي التهيئة   في نفس رمز الكائن كائنا   ولدت، لكنها ليست ما يعادلها.   ومن المعروف أن التهيئة لكما   توجيه التهيئة، وأنه لا   بالضبط ما قد يتوقع المرء. ال   ويتم إنجاز التهيئة من خلال   والاحتجاج المباشر للY Y :: (الباحث).

     

ووالتهيئة للb و c   أكثر تعقيدا. في الواقع، انهم جدا   مركب. هذه هي كل نسخة   التهيئة. في حالة   تهيئة ب، ونحن يطلب   إنشاء مؤقت مجهول   من نوع Y، تهيئة مع قيمة   1066. ثم نستخدم هذا مؤقتة مجهول كمعلمة إلى النسخة   منشئ لفئة Y تهيئة   ب. وأخيرا، فإننا ندعو المدمر ل   المجهول مؤقت.

لاختبار هذا، لقد فعلت ذلك لفئة بسيطة مع عضو البيانات (البرنامج المرفق في النهاية) وكانت النتائج مثيرة للدهشة. ويبدو أن للحالة ج، شيد الكائن منشئ نسخة بدلا من المقترح في الكتاب.

لا أحد يعرف إذا كان معيار اللغة قد تغيرت أم أن هذا مجرد ميزة تعظيم الاستفادة من مترجم؟ كنت باستخدام Visual Studio 2008.

ونموذج التعليمات البرمجية:

#include <iostream>

class Widget
{
    std::string name;
public:
    // Constructor
    Widget(std::string n) { name=n; std::cout << "Constructing Widget " << this->name << std::endl; }
    // Copy constructor
    Widget (const Widget& rhs) { std::cout << "Copy constructing Widget from " << rhs.name << std::endl; }
    // Assignment operator
    Widget& operator=(const Widget& rhs) { std::cout << "Assigning Widget from " << rhs.name << " to " << this->name << std::endl; return *this; }
};

int main(void)
{
    // construct
    Widget a("a");
    // copy construct
    Widget b(a);
    // construct and assign
    Widget c("c"); 
    c = a;
    // copy construct!
    Widget d = a;
    // construct!
    Widget e = "e";
    // construct and assign
    Widget f = Widget("f");

    return 0;
}

وإخراج:

Constructing Widget a

Copy constructing Widget from a

Constructing Widget c
Assigning Widget from a to c

Copy constructing Widget from a

Constructing Widget e

Constructing Widget f
Copy constructing Widget from f

وكنت معظم فوجئت نتائج بناء d و e. على وجه الدقة، كنت أتوقع كائن فارغ المراد إنشاؤها، ثم كائن المراد إنشاؤها وتعيين إلى كائن فارغ. في الممارسة العملية، تم إنشاء الكائنات منشئ نسخة.

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

المحلول

وبناء الجملة

X a = b;

وحيث a و b من نوع X يعني دائما بناء نسخة. مهما كانت المتغيرات، مثل:

X a = X();

وتستخدم، ليس هناك مهمة مستمرة، ولم تكن أبدا. سيكون بناء وإسناد يكون شيئا مثل:

X a;
a = X();

نصائح أخرى

ويسمح المترجم إلى حالات الأمثل b وc أن تكون هي نفسها كما a. وعلاوة على ذلك، بناء نسخة والمكالمات عامل التعيين يمكن القضاء عليها بالكامل من قبل مترجم على أي حال، لذلك كل ما تراه ليس بالضرورة الشيء نفسه مع المجمعين مختلفة أو إعدادات حتى مترجم.

واعتبارا من C ++ 17، كل ثلاثة من هذه <م> هي ما يعادلها (ما لم Y::Y(int) هو explicit، وهو ما من شأنه ببساطة عدم السماح c) بسبب ما وغالبا ما تسمى <لأ href = "HTTP: // en.cppreference.com/w/cpp/language/copy_elision "يختلط =" noreferrer نوفولو "> إلزامية نسخة ترخيم .

وY c = 1066; حتى يخلق فقط الكائن Y واحد لأن نتيجة تحويل ضمني Y هي prvalue التي يتم استخدامها لتهيئة c بدلا من إنشاء مؤقتة.

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