Mengapakah Move Constructor Tidak Dipanggil dalam C 11 Apabila Penyingkiran Salin Didayakan?

DDD
Lepaskan: 2024-11-06 09:46:02
asal
248 orang telah melayarinya

Why Is the Move Constructor Not Called in C  11 When Copy Elision Is Enabled?

C 11 Move Constructor Not Called, Default Constructor Preferred

Apabila bekerja dengan kelas dalam C , dijangkakan bahawa move constructor akan digunakan untuk pemindahan sumber yang cekap. Walau bagaimanapun, dalam sesetengah kes, pembina lalai mungkin dipilih secara tidak dijangka.

Pernyataan Masalah

Pertimbangkan kelas berikut:

<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

Dengan penggunaan sampel:

<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

Keluaran yang dijangkakan ialah:

ctor
test
copy
test
ctor move test
Salin selepas log masuk

Walau bagaimanapun, baris terakhir secara tidak dijangka mengeluarkan "ctor" dan bukannya "move."

Penjelasan

Mengikut piawaian C 11, pembina bergerak harus dipanggil dalam situasi tertentu. Dalam kes ini, pergerakan harus berlaku apabila membina z dengan X("ujian"). Walau bagaimanapun, pembina lalai dipanggil sebaliknya.

Tingkah laku ini disebabkan oleh penyingkiran salinan, teknik pengoptimuman yang membolehkan pengkompil membina secara langsung sementara ke dalam sasaran tanpa melakukan operasi salinan atau pemindahan. Pengoptimuman ini digunakan dalam kes di mana pengkompil menentukan bahawa operasi salin/pindah adalah tidak diperlukan dan boleh dihapuskan.

Dalam senario yang diberikan, pengkompil menganggap X("ujian") sementara sebagai calon untuk penghapusan salinan, kerana ia dicipta dan dimusnahkan secara automatik dalam ungkapan yang sama. Akibatnya, ia mengetepikan operasi bergerak dan membina z secara langsung menggunakan data sementara, mengakibatkan panggilan kepada pembina lalai.

Kesimpulan

Penyingkiran salin boleh membawa kepada yang tidak dijangka tingkah laku apabila bekerja dengan pembina bergerak, kerana ia boleh menghalang pembina bergerak daripada digunakan dalam situasi di mana ia dijangka. Penyusun boleh menggunakan penyingkiran salinan berdasarkan heuristik pengoptimuman mereka, yang boleh berbeza-beza antara penyusun dan tetapan pengoptimuman. Adalah penting untuk mengetahui penyingkiran salinan dan potensi kesannya terhadap tingkah laku program.

Atas ialah kandungan terperinci Mengapakah Move Constructor Tidak Dipanggil dalam C 11 Apabila Penyingkiran Salin Didayakan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!