Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah `push_back` Mencetuskan Panggilan Pembina Berbilang Salinan dalam Vektor?

Mengapakah `push_back` Mencetuskan Panggilan Pembina Berbilang Salinan dalam Vektor?

Barbara Streisand
Barbara Streisandasal
2024-11-01 07:17:02533semak imbas

Why Does `push_back` Trigger Multiple Copy Constructor Calls in a Vector?

Tekan_balik Vektor dan Misteri Seruan Pembina Berbilang Salin

Apabila bekerja dengan vektor, seseorang mungkin menjangkakan operasi tolak_balik hanya memerlukan segelintir panggilan pembina salinan. Walau bagaimanapun, kes tertentu boleh mendedahkan tingkah laku yang tidak dijangka, seperti berbilang panggilan.

Pertimbangkan coretan kod berikut:

<code class="cpp">class Myint {
    int my_int;
public:
    Myint() : my_int(0) { /* ... */ }
    Myint(const Myint& x) : my_int(x.my_int) { /* ... */ }
};

int main() {
    vector<Myint> myints;
    Myint x;

    myints.push_back(x); // Call 1
    x.set(1);
    myints.push_back(x); // Call 2
}</code>

Secara intuitif, kami menjangkakan dua panggilan pembina salinan: satu untuk push_back pertama dan satu lagi untuk yang kedua. Walau bagaimanapun, output menceritakan kisah yang berbeza:

Call 1 (default constructor)
Call 2 (copy constructor: my_int = 0)
Call 3 (copy constructor: my_int = 0)
Call 4 (copy constructor: my_int = 1)

Mengapa panggilan tambahan?

Dinamik Vektor Dalaman

Secara dalaman, vektor biasanya memperuntukkan jumlah memori tertentu untuk penyimpanan. Apabila ruang yang diperuntukkan telah habis, vektor mesti memperuntukkan semula lebih banyak memori. Pengagihan semula ini mencetuskan salinan elemen sedia ada ke dalam memori baharu.

Dalam kod yang diberikan, tolak_balik kedua memerlukan pengagihan semula. Walaupun fakta bahawa pembina untuk Myint digunakan hanya dua kali, pembina salinan digunakan tiga kali. Ini kerana pembina salinan digunakan untuk memindahkan elemen pertama ke dalam memori yang baru diperuntukkan, dimulakan dengan nilai asalnya (my_int = 0), dan kemudian pembina salinan dipanggil semula untuk mencipta elemen kedua, dimulakan dengan nilai yang dikemas kini ( my_int = 1).

Mengoptimumkan Prestasi

Untuk mengurangkan salinan yang tidak diperlukan ini, adalah disyorkan untuk:

  • Rizab Memori: Dengan meningkatkan kapasiti awal vektor, anda boleh menghalang pengagihan semula dan meminimumkan operasi penyalinan.
  • Gunakan Emplace_back: Kaedah ini membolehkan anda membina elemen secara terus di tempat, mengelakkan salinan atau pergerakan.

Dalam kes ini, menggunakan rizab untuk praperuntukkan memori akan mengurangkan panggilan pembina salinan kepada dua dengan berkesan. Selain itu, emplace_back(0) akan menghapuskan salinan sama sekali, menghasilkan prestasi yang optimum.

Atas ialah kandungan terperinci Mengapakah `push_back` Mencetuskan Panggilan Pembina Berbilang Salinan dalam Vektor?. 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