Rumah >pembangunan bahagian belakang >C++ >`make_shared` lwn. `shared_ptr` yang Dimulakan oleh Pembina: Apakah Perbezaan Prestasi dan Keselamatan Pengecualian?

`make_shared` lwn. `shared_ptr` yang Dimulakan oleh Pembina: Apakah Perbezaan Prestasi dan Keselamatan Pengecualian?

Barbara Streisand
Barbara Streisandasal
2024-12-11 00:40:16406semak imbas

`make_shared` vs. Constructor-Initialized `shared_ptr`: What's the Performance and Exception Safety Difference?

Perbezaan antara make_shared dan Constructor-Initialized shared_ptr

Senario

Pertimbangkan coretan kod berikut:

std::shared_ptr<Object> p1 = std::make_shared<Object>("foo");
std::shared_ptr<Object> p2(new Object("foo"));

Memahami sebabnya make_shared adalah lebih cekap daripada menggunakan shared_ptr pembina secara langsung memerlukan analisis langkah demi langkah bagi operasi yang terlibat.

Perbandingan Operasi

make_shared

  • Melaksanakan peruntukan timbunan tunggal untuk mencipta blok memori bersebelahan untuk kedua-dua blok kawalan (data meta) dan terurus object.

Constructor-Initialized shared_ptr

  • Memanggil Obj("foo") baharu, yang mencipta peruntukan timbunan untuk objek terurus.
  • Kemudian , pembina shared_ptr dipanggil, yang melaksanakan peruntukan timbunan lain untuk kawalan blok.

Peruntukan Memori

make_shared memperuntukkan memori sekali sahaja, manakala shared_ptr yang dimulakan pembina memperuntukkan memori dua kali. Ini menjadikan make_shared lebih cekap.

Keselamatan Pengecualian

Dalam C 17, susunan penilaian argumen fungsi telah disemak, menghapuskan kebimbangan keselamatan pengecualian dengan pendekatan shared_ptr yang dimulakan oleh pembina. Walau bagaimanapun, mari kita pertimbangkan contoh:

void F(const std::shared_ptr<Lhs> &lhs, const std::shared_ptr<Rhs> &rhs) { /* ... */ }

F(std::shared_ptr<Lhs>(new Lhs("foo")), std::shared_ptr<Rhs>(new Rhs("bar")));

Jika pengecualian dilemparkan semasa pembina Rhs, memori yang diperuntukkan untuk Lhs akan hilang kerana ia tidak dihantar serta-merta kepada pembina shared_ptr. make_shared mengelakkan isu ini dengan menghapuskan langkah perantaraan ini.

Kelemahan make_shared

Walau bagaimanapun, make_shared mempunyai kelemahan: kerana ia memperuntukkan blok kawalan dan objek terurus dalam satu blok timbunan, memori untuk kedua-duanya tidak boleh diagihkan secara bebas. Ini bermakna penunjuk lemah boleh memastikan blok kawalan hidup selama-lamanya, berpotensi menghalang kedua-dua blok kawalan dan objek terurus daripada diagihkan.

Atas ialah kandungan terperinci `make_shared` lwn. `shared_ptr` yang Dimulakan oleh Pembina: Apakah Perbezaan Prestasi dan Keselamatan Pengecualian?. 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