Pelajaran modul (2/2)
std::weak_ptr
Meskipun std::shared_ptr sangat berguna, hanya mengandalkan kepemilikan bersama dapat menyebabkan masalah yang dikenal sebagai referensi melingkar (atau ketergantungan siklik).
Jika dua atau lebih objek masing-masing berisi shared_ptr yang menunjuk ke objek lainnya, maka loop tertutup akan dibuat. Dalam situasi ini, jumlah referensi dari kedua objek tidak akan pernah mencapai nol, sehingga mencegah dealokasi dan menyebabkan kebocoran memori.
Apa itu std::weak_ptr
Untuk memutus siklus kepemilikan, perpustakaan standar menawarkan std::weak_ptr. Ini adalah penunjuk cerdas yang mengamati objek yang dikelola oleh shared_ptr, tetapi tanpa menambah jumlah referensi.
Ia tidak memiliki sumber daya secara langsung, sehingga tidak mencegah kehancurannya.
#include <memory>
std::shared_ptr<int> shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared; // Does not increment reference count!Memverifikasi dan Mengakses Sumber Daya
Karena weak_ptr tidak memiliki sumber daya, sumber daya dapat dibatalkan alokasinya kapan saja (bila semua instance shared_ptr terkait berada di luar cakupan).
Untuk menggunakan sumber daya yang diamati, kita harus:
- Cek apakah masih valid menggunakan
expired(). - Ubah sementara
weak_ptrmenjadishared_ptrmenggunakan metodelock(). Jika sumber daya masih aktif,lock()mengembalikanshared_ptryang valid, jika tidak maka akan mengembalikan penunjuk nol (nullptr).
if (!weak.expired()) {
// lock() creates a temporary shared_ptr to ensure safe access
if (std::shared_ptr<int> sharedAccess = weak.lock()) {
std::cout << *sharedAccess << std::endl;
}
} else {
std::cout << "Resource deallocated!" << std::endl;
}Cobalah sendiri
Deklarasikan std::weak_ptr<int> bernama wPtr yang diinisialisasi dari sPtr. Kemudian cetak hasil boolean yang dikembalikan oleh wPtr.expired() menggunakan std::cout.
Tunjukkan petunjuk
Deklarasikan `weak_ptr` yang menunjukkan tipe generik yang sama `<int>` dan tetapkan `sPtr` langsung ke sana.
Solusi tersedia setelah 3 upaya
Gunakan metode lock() pada wPtr untuk mendapatkan shared_ptr sementara. Jika operasi berhasil (penunjuknya bukan nol), cetak nilai yang direferensikan.
Tunjukkan petunjuk
Inisialisasi variabel di dalam blok `if` dengan memanggil `wPtr.lock()`, lalu cetak sumber daya yang melakukan dereferensi dengan tanda bintang `*`.
Solusi tersedia setelah 3 upaya