Middle
std::shared_ptr'da referanslar soni qanday ishlaydi?
sobes.tech AI
AIdan javob
std::shared_ptr ichidagi referanslar soni alohida obyektda saqlanadi: nazorat blokida (control block).
Bu nazorat bloki quyidagi holatlarda yaratiladi:
- Birinchi marta
std::shared_ptrni ko‘rsatkichdan yaratishda. - Maxsus o‘chirishchi yoki ajratuvchi bilan
std::shared_ptrni yaratishda. std::make_sharedyokistd::allocate_sharedishlatilganda.
Ushbu nazorat bloki kamida ikki hisoblagichni o‘z ichiga oladi:
- Kuchli referanslar hisoblagichi (strong count):
std::shared_ptryaratilganda yoki nusxa ko‘chirganda oshadi.std::shared_ptryo‘q qilinayotganda kamayadi. Bu hisoblagich nolga teng bo‘lsa, boshqarilayotgan obyekt bo‘shatiladi. - Zaif referanslar hisoblagichi (weak count):
std::shared_ptrdanstd::weak_ptryaratilganda oshadi.std::weak_ptryo‘q qilinayotganda kamayadi. Ikkala hisoblagich — kuchli va zaif — nolga teng bo‘lsa, nazorat bloki bo‘shatiladi.
std::make_shared dan foydalanish to‘g‘ridan-to‘g‘ri new bilan yaratishga nisbatan afzaldir, chunki u obyekt va nazorat blokini bitta xotira blokida ajratishi mumkin, bu esa ishlash tezligini oshiradi va bo‘linishni kamaytiradi.
Hisoblagichlar atomik bo‘lib, std::shared_ptr ko‘p ipli muhitda xavfsiz foydalanishni ta’minlaydi, garchi boshqarilayotgan obyektga kirish odatda sinxronlashtirilmagan.
Misol:
#include <iostream>
#include <memory>
struct MyObject {
int data;
MyObject(int d) : data(d) {
std::cout << "MyObject(" << data << ") yaratildi\n";
}
~MyObject() {
std::cout << "MyObject(" << data << ") yo‘q qilindi\n";
}
};
int main() {
std::shared_ptr<MyObject> ptr1 = std::make_shared<MyObject>(10);
// kuchli hisoblagich: 1, zaif hisoblagich: 0
{
std::shared_ptr<MyObject> ptr2 = ptr1;
// kuchli hisoblagich: 2, zaif hisoblagich: 0
std::weak_ptr<MyObject> weak_ptr = ptr1;
// kuchli hisoblagich: 2, zaif hisoblagich: 1
if (auto locked_ptr = weak_ptr.lock()) {
// kuchli hisoblagich: 3, zaif hisoblagich: 1 (vaqtinchalik lock ichida)
std::cout << "Obyekt ma'lumotlari: " << locked_ptr->data << std::endl;
}
// kuchli hisoblagich: 2, zaif hisoblagich: 1
} // ptr2 scope dan chiqadi
// kuchli hisoblagich: 1, zaif hisoblagich: 1
// Ob'ekt hali yo‘q qilinmagan, chunki kuchli hisoblagich == 1
{
std::weak_ptr<MyObject> weak_ptr2 = ptr1;
// kuchli hisoblagich: 1, zaif hisoblagich: 2
} // weak_ptr2 scope dan chiqadi
// kuchli hisoblagich: 1, zaif hisoblagich: 1
} // ptr1 scope dan chiqadi
// kuchli hisoblagich: 0, zaif hisoblagich: 1
// Ob'ekt yo‘q qilinadi, chunki kuchli hisoblagich 0 ga teng
// Nazorat bloki zaif hisoblagich 0 bo‘lgach, ochiriladi