Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapa Pembina C 11 Move Saya Tidak Dipanggil dalam Kes Ini?

Mengapa Pembina C 11 Move Saya Tidak Dipanggil dalam Kes Ini?

Susan Sarandon
Susan Sarandonasal
2024-11-05 01:49:02447semak imbas

Why Doesn't My C  11 Move Constructor Get Called in This Case?

C 11 Move Constructor Tidak Dipanggil, Default Constructor Diutamakan

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>

Dan penggunaannya:

<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>

Outputnya ialah:

ctor
test
copy
test
ctor   <-- why not move?
test

Dalam VS2010, menggunakan tetapan lalai, seseorang akan menjangkakan objek terakhir (z) akan dibina bergerak dan bukannya lalai- dibina. Menggunakan X z( move(X("test")) ) menghasilkan output yang dijangkakan: ctor move test. Bolehkah ini menjadi kes NRVO?

Soalan

Adakah pembina bergerak dipanggil mengikut piawaian C 11? Jika ya, mengapa ia tidak dipanggil?

Jawapan

Tingkah laku yang diperhatikan adalah disebabkan penyingkiran salinan. Pengkompil boleh terus membina sementara ke dalam sasaran yang hendak disalin/dialihkan ke dalamnya, sekali gus mengecualikan panggilan pembina salin/pindah dan pemusnah.

Situasi di mana penyingkiran salinan boleh digunakan digariskan dalam §12.8. 32 daripada standard C 11:

  • Dalam fungsi dengan jenis pulangan kelas, jika ungkapan pulangan ialah objek automatik tidak meruap dengan jenis yang sama dengan jenis pulangan.
  • Dalam ungkapan lontaran, jika operan ialah objek automatik tidak meruap dengan skop yang tidak melangkaui blok cuba yang disertakan.
  • Apabila objek kelas yang belum terikat pada rujukan akan disalin /dipindahkan ke objek kelas dengan jenis yang sama.
  • Apabila pengendali pengecualian mengisytiharkan objek daripada jenis yang sama dengan objek pengecualian dengan menganggap pengisytiharan pengecualian sebagai alias.

Dalam kes ini, pengkompil dapat mengenepikan operasi salinan atau alih antara X("ujian") sementara dan z sasaran, menghasilkan tingkah laku yang diperhatikan.

Atas ialah kandungan terperinci Mengapa Pembina C 11 Move Saya Tidak Dipanggil dalam Kes Ini?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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