ماڈیول اسباق (2/2)
std::weak_ptr
اگرچہ std::shared_ptr انتہائی مفید ہے، لیکن مکمل طور پر مشترکہ ملکیت پر انحصار کرنا ایک مسئلہ کا باعث بن سکتا ہے جسے سرکلر حوالہ (یا چکری انحصار) کہا جاتا ہے۔
اگر دو یا زیادہ اشیاء میں سے ہر ایک میں ایک shared_ptr ہوتا ہے جو دوسرے کی طرف اشارہ کرتا ہے تو ایک بند لوپ بن جاتا ہے۔ اس صورت حال میں، کسی بھی چیز کا حوالہ شمار کبھی صفر تک نہیں پہنچے گا، ڈیل لوکیشن کو روکتا ہے اور میموری لیک ہونے کا سبب بنتا ہے۔
کیا ہے std::weak_ptr
ملکیت کے چکروں کو توڑنے کے لیے، معیاری لائبریری std::weak_ptr پیش کرتی ہے۔ یہ ایک سمارٹ پوائنٹر ہے جو shared_ptr کے زیر انتظام کسی چیز کا مشاہدہ کرتا ہے، لیکن حوالہ کی تعداد میں اضافہ کیے بغیر۔
یہ براہ راست وسائل کا مالک نہیں ہے، لہذا یہ اس کی تباہی کو نہیں روکتا۔
#include <memory>
std::shared_ptr<int> shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared; // Does not increment reference count!وسائل کی تصدیق اور رسائی
چونکہ ایک weak_ptr وسائل کا مالک نہیں ہے، اس لیے وسائل کو کسی بھی وقت ڈیلوکٹ کیا جا سکتا ہے (جب تمام متعلقہ shared_ptr مثالیں دائرہ کار سے باہر ہو جائیں)۔
مشاہدہ شدہ وسائل کو استعمال کرنے کے لیے، ہمیں یہ کرنا چاہیے:
- چیک کریں کہ آیا یہ
expired()استعمال کرکے اب بھی درست ہے۔ lock()طریقہ استعمال کرتے ہوئے عارضی طور پرweak_ptrکوshared_ptrمیں تبدیل کریں۔ اگر وسیلہ اب بھی فعال ہے،lock()ایک درستshared_ptrلوٹاتا ہے، بصورت دیگر یہ ایک کالعدم پوائنٹر (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;
}خود ہی آزمائیں۔
ایک std::weak_ptr<int> کا اعلان کریں جس کا نام wPtr sPtr سے شروع کیا گیا ہے۔ پھر std::cout کا استعمال کرتے ہوئے wPtr.expired() کے ذریعہ واپس کردہ بولین نتیجہ پرنٹ کریں۔
اشارہ دکھائیں۔
اسی عام قسم کی نشاندہی کرنے والے `کمزور_ptr` کا اعلان کریں `<int>` اور اسے براہ راست `sPtr` تفویض کریں۔
3 کوششوں کے بعد حل دستیاب ہے۔
عارضی مشترکہ_ptr حاصل کرنے کے لیے wPtr پر lock() طریقہ استعمال کریں۔ اگر آپریشن کامیاب ہو جاتا ہے (پوائنٹر کالعدم نہیں ہے)، ڈیریفرنس ویلیو پرنٹ کریں۔
اشارہ دکھائیں۔
`wPtr.lock()` کو کال کرکے ایک `if` بلاک کے اندر ایک متغیر کو شروع کریں، پھر ستارہ `*` سے اس کا حوالہ دیتے ہوئے وسائل کو پرنٹ کریں۔
3 کوششوں کے بعد حل دستیاب ہے۔