Middle
Как работи shared_ptr в C++?
sobes.tech AI
Отговор от AI
shared_ptr — това е интелигентен указател, реализиращ семантиката на владение на споделен ресурс. Той съхранява указател към обекта и указател към управляващия блок.
Управляващ блок съдържа:
- Брояч на силните препратки (reference count).
- Брояч на слабите препратки (weak count).
- Потребителски функтор за изтриване (deleter), ако е зададен.
- Потребителски аллокатор, ако е зададен.
- Указател към съхранявания обект (същото, което се съхранява в самия
shared_ptr).
Принцип на работа:
- Създаване: При създаване на първия
shared_ptr, сочещ към обект, се създава управляващият блок, броячите на препратки се инициализират: силни — 1, слаби — 0.std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // Създава обект int и управляващ блок - Копиране: При копиране на
shared_ptrброячът на силните препратки в управляващия блок се увеличава с 1.std::shared_ptr<int> ptr2 = ptr1; // Увеличава брояча на силните препратки - Присвояване: При присвояване на
shared_ptrкъм стар ресурс, броячът на силните препратки се намалява за стария ресурс и се увеличава за новия.std::shared_ptr<int> ptr3; ptr3 = ptr1; // Намалява брояча на стария ресурс, увеличава за новия - Премахване: При унищожаване на
shared_ptr(например, излизане от обхвата) броячът на силните препратки се намалява.{ std::shared_ptr<int> ptr4 = ptr1; // Увеличава брояча на силните препратки // ptr4 излиза от обхвата } // Намалява брояча на силните препратки - Освобождаване на ресурса: Когато броячът на силните препратки достигне нула, ресурсът (обектът, към който сочи
shared_ptr) се изтрива с помощта на зададения функтор за изтриване (илиdeleteпо подразбиране). - Освобождаване на управляващия блок: Управляващият блок се освобождава, когато и двата брояча (силните и слабите) достигнат нула.
Предимства:
- Автоматично управление на паметта за споделените ресурси.
- Безопасност срещу двойно освобождаване.
- Поддръжка на потребителски функтори за изтриване.
Недостатъци:
- Цикличните препратки могат да доведат до изтичане на памет (решава се с
weak_ptr). - Леко увеличение на разходите поради управляващия блок и атомарните операции с броячите.
- Потокобезопасност на операциите с самия
shared_ptr(копиране, присвояване, промяна на съхранявания указател), но не и с обекта, към който сочи.