Petunjuk pintar ialah konsep yang sangat penting dalam C++ Peranannya adalah untuk membantu pengaturcara mencegah kebocoran memori dan pada masa yang sama menyediakan kaedah pengurusan memori yang lebih mudah dan fleksibel. Artikel ini akan menjalankan penerokaan terperinci tentang konsep, jenis dan penggunaan penunjuk pintar.
Penunjuk pintar ialah teknologi pengurusan memori C++ moden yang menyimpan penunjuk yang merangkum peruntukan dan pelepasan memori dalam objek penunjuk pintar. Memandangkan bahasa C++ tidak mengurus memori secara automatik untuk pengaturcara, dan pengaturcara sering terlupa untuk melepaskan memori, menggunakan penunjuk pintar boleh mengurangkan kemungkinan masalah ini.
Satu lagi kelebihan penunjuk pintar ialah ia boleh meningkatkan kebolehselenggaraan atur cara, kerana ia memindahkan pelepasan memori dan pengurusan kitaran hayat objek daripada pengaturcara ke pustaka penunjuk pintar. Dalam C++ moden, kod yang menggunakan penunjuk pintar cenderung menjadi lebih teguh dan kurang terdedah kepada ralat berbanding kod yang menggunakan penunjuk mentah.
Terdapat tiga jenis penunjuk pintar dalam C++: unique_ptr, shared_ptr dan weak_ptr. Kesemuanya ditakrifkan dalam
(1) unique_ptr
unique_ptr ialah penunjuk eksklusif, yang memastikan hanya satu penunjuk pintar boleh menunjuk ke objek pada bila-bila masa. Dalam erti kata lain, unique_ptr melarang berbilang penunjuk menunjuk ke objek yang sama. Jika anda ingin memindahkan penunjuk unique_ptr ke penunjuk pintar yang lain, anda perlu menggunakan fungsi std::move().
Berikut ialah contoh kod untuk menunjukkan penggunaan asas unique_ptr:
std::unique_ptr<int> up(new int(10)); // 声明unique_ptr指针,并分配一个int类型的动态内存区域 std::cout << *up << std::endl; // 输出10 *up = 20; // 修改动态内存中的值 std::cout << *up << std::endl; // 输出20
Perlu diambil perhatian bahawa apabila penunjuk unique_ptr meninggalkan skopnya, memori dinamik yang ditunjukkannya akan dikeluarkan secara automatik. (Walaupun terdapat pengecualian yang dilemparkan)
(2) shared_ptr
shared_ptr boleh berkongsi objek yang sama dengan berbilang penunjuk, dan anda boleh menggunakan fungsi use_count() untuk mendapatkan bilangan penunjuk yang menunjuk ke objek yang sama. Oleh kerana berbilang penunjuk boleh menunjuk ke objek yang sama, penjagaan mesti diambil untuk mengelakkan situasi rujukan bulat, yang boleh menyebabkan kebocoran ingatan.
Menggunakan kod sampel adalah seperti berikut:
std::shared_ptr<int> sp1(new int(10)); std::shared_ptr<int> sp2 = sp1; std::cout << *sp1 << std::endl; // 输出10 std::cout << *sp2 << std::endl; // 输出10 std::cout << sp1.use_count() << std::endl; // 输出2
Perlu diambil perhatian bahawa setiap kali penuding_ptr kongsi baharu menghala ke kawasan memori yang sama, kiraan rujukan dalam kawasan memori akan meningkat sebanyak 1. Begitu juga, apabila penunjuk meninggalkan skopnya, kiraan rujukan dikurangkan dengan sewajarnya. Memori hanya akan dikeluarkan apabila kiraan rujukan mencapai 0. (Walaupun terdapat pengecualian yang dilemparkan)
(3) weak_ptr
weak_ptr ialah versi shared_ptr yang lebih ringan. Ia tidak boleh mengawal objek yang ditunjuk dan perlu ditukar kepada shared_ptr sebelum digunakan. Kerana ia tidak menjejaskan pengiraan rujukan, ia tidak menyebabkan kebocoran memori. Walau bagaimanapun, perlu diingatkan bahawa apabila menggunakan weak_ptr, anda perlu memastikan objek yang ditunjuk wujud, jika tidak menggunakan antara muka yang disediakannya akan menyebabkan ralat program.
Berikut ialah contoh penggunaan weak_ptr:
std::shared_ptr<int> sp1(new int(10)); std::weak_ptr<int> wp = sp1; std::cout << *wp.lock() << std::endl; // 使用weak_ptr提供的lock()函数将其转化为shared_ptr,并访问内存中的值 std::cout << wp.use_count() << std::endl; // 输出1
Perlu diambil perhatian bahawa apabila objek runcing dipadamkan, shared_ptr yang dikembalikan oleh weak_ptr.lock() akan kosong.
Menggunakan penunjuk pintar boleh memudahkan tugas pengurusan ingatan kerana mereka boleh melepaskan memori dinamik yang mereka uruskan secara automatik. Apabila menggunakan penunjuk pintar, ia perlu dimulakan kepada nilai pulangan peruntukan memori dinamik. Di bawah ialah beberapa contoh kod untuk membantu pembaca lebih memahami penggunaan penunjuk pintar.
// 使用unique_ptr std::unique_ptr<int> up(new int(10)); std::unique_ptr<float[]> u_arr( new float[5] ); // 对数组使用unique_ptr // 使用shared_ptr std::shared_ptr<int> sp(new int(10)); std::shared_ptr<double> sp_arr(new double[5], [](double* p){ delete[] p; }); // 对数组使用shared_ptr,并在内部传递匿名的lambda表达式释放动态内存 std::shared_ptr<Base> spb = std::make_shared<Base>(); // 使用std::make_shared创建shared_ptr指针 std::shared_ptr<Derived> spd = std::make_shared<Derived>(); // 使用weak_ptr std::weak_ptr<int> wp; if (auto sp = wp.lock()) // 使用wp.lock()检查指向的对象 { // 操作所指向的对象 } else { // 找不到所指向的对象 }
Perlu diingat bahawa jika penunjuk biasa dan penunjuk pintar digunakan untuk menghala ke memori dinamik yang sama, penunjuk pintar akan dimusnahkan sebelum penuding biasa, yang boleh menyebabkan penuding biasa menghala kepada yang dilepaskan dengan mudah ( tidak boleh digunakan) ruang ingatan.
Petunjuk pintar ialah kaedah pengurusan memori C++ yang sangat berguna Ia boleh menghalang kebocoran memori pada tahap tertentu dan juga meningkatkan kebolehselenggaraan program. Dalam piawaian selepas C++11, petunjuk pintar disyorkan sebagai kaedah pengurusan memori pilihan. Dalam proses pembangunan sebenar, anda perlu memilih jenis penunjuk pintar untuk digunakan mengikut situasi tertentu untuk mencapai kesan pengurusan memori yang terbaik.
Atas ialah kandungan terperinci Terokai petunjuk pintar dalam C++. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!