Rumah > pembangunan bahagian belakang > C++ > Mengapakah C 11 Move Constructor Tidak Dipanggil Apabila Objek Sementara Digunakan untuk Memulakan Objek Lain?

Mengapakah C 11 Move Constructor Tidak Dipanggil Apabila Objek Sementara Digunakan untuk Memulakan Objek Lain?

Mary-Kate Olsen
Lepaskan: 2024-11-05 05:06:02
asal
1074 orang telah melayarinya

Why is the C  11 Move Constructor Not Called When a Temporary Object is Used to Initialize Another Object?

C 11 Move Constructor Not Called, Default Constructor Preferred

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>
Salin selepas log masuk

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>
Salin selepas log masuk

Walau bagaimanapun, bukannya output yang dijangka menunjukkan pembina bergerak dipanggil untuk z, sebaliknya pembina lalai digunakan.

Penjelasan Gelagat:
Tingkah laku yang diperhatikan adalah disebabkan oleh pengoptimuman pengkompil yang dipanggil

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.

Penyelesaian:

Untuk memaksa pembina bergerak menjadi dipanggil, kita boleh menggunakan std::move() untuk menunjukkan secara jelas bahawa perpindahan harus dilakukan:

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!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan