Penerangan:
Apabila bekerja dengan move semantik dalam C 11, ia mungkin untuk menghadapi senario di mana pembina bergerak secara tidak dijangka dilangkau memihak kepada pembina lalai. Artikel ini meneroka isu ini, mengkaji sebab asas dan menyediakan penyelesaian.
Masalah:
Pertimbangkan kelas X berikut dengan pembina yang mengeluarkan mesej:
<code class="cpp">class X { public: explicit X(char* c) { cout << "ctor" << endl; init(c); } X(X& lv) { cout << "copy" << endl; init(lv.c_); } X(X&& rv) { cout << "move" << endl; c_ = rv.c_; rv.c_ = nullptr; } const char* c() { return c_; } private: void init(char *c) { c_ = new char[strlen(c)+1]; strcpy(c_, c); } char* c_; };</code>
Dalam penggunaan sampel yang disediakan di bawah, kami mencipta tiga objek:
<code class="cpp">X x("test"); cout << x.c() << endl; X y(x); cout << y.c() << endl; X z( X("test") ); cout << z.c() << endl;</code>
Walau bagaimanapun, bukannya output yang dijangka menunjukkan pembina bergerak dipanggil untuk z, sebaliknya pembina lalai digunakan.
Penjelasan Gelagat:penyingkiran salinan. C 11 membenarkan penyusun untuk meninggalkan penyalinan/menggerakkan objek dalam situasi tertentu untuk meningkatkan prestasi. Salah satu daripada situasi ini ialah apabila objek sementara akan disalin/dialihkan ke objek dengan jenis cv-tidak layak yang sama.
Dalam baris terakhir kod sampel kami, X("ujian") mencipta X sementara objek dan ia mempunyai jenis cv-tidak layak yang sama seperti sasaran (z). Oleh itu, pengkompil dibenarkan untuk mengenepikan salinan dan memindahkan pembina, membina objek sementara secara langsung ke dalam z tanpa menggunakan salah satu pembina.
Dengan pengubahsuaian ini, output yang dijangkakan dihasilkan, mengesahkan penglibatan pembina bergerak.
Atas ialah kandungan terperinci Mengapakah C 11 Move Constructor Tidak Dipanggil Apabila Objek Sementara Digunakan untuk Memulakan Objek Lain?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!