Middle
std::shared_ptr'деги шилтемелердин саноочу кандай иштейт?
sobes.tech AI
AIден жооп
std::shared_ptrтүн шилтемелеринин саноолору өзүнчө объектте сакталат — башкаруу блогунда (control block).
Бул башкаруу блогу түзүлөт:
std::shared_ptrбиринчи жолу түзүлгөндө көрсөткүчтөн.- Колдонуучу тарабынан жуугуч же аллокатор менен түзүлгөндө.
std::make_sharedжеstd::allocate_sharedколдонулганда.
Бул башкаруу блогунда кеминде эки эсептегич болот:
- Катуу шилтемелердин эсептегичи (strong count):
std::shared_ptrтүзүлгөндө же көчүрүлгөндө көбөйөт, жок кылынганда азаяды. Эгер бул эсептегич нөлгө жетсе, башкарылуучу объект бошотулат. - Слаб шилтемелердин эсептегичи (weak count):
std::weak_ptrтүзүлгөндө көбөйөт, жок кылынганда азаяды. Эгер эки эсептегич — катуу жана слаб — нөлгө жетсе, башкаруу блогу бошотулат.
std::make_shared колдонуу түздөн-түз new менен түзүүдөн артыкчылыкка ээ, анткени ал объектти жана башкаруу блогун бир эле эс тутум бөлүмүндө алоқа кылып, иштөөчәндикти жакшыртат жана фрагментацияны азайтат.
Атомик эсептегичтер std::shared_ptr-ди көптөгөн агымдарда колдонууга коопсуз кылат, бирок башкарылуучу объектке кирүү алдын ала синхрондоштурулбайт.
Мисал:
#include <iostream>
#include <memory>
struct MyObject {
int data;
MyObject(int d) : data(d) {
std::cout << "MyObject(" << data << ") түзүлдү\n";
}
~MyObject() {
std::cout << "MyObject(" << data << ") жок кылынды\n";
}
};
int main() {
std::shared_ptr<MyObject> ptr1 = std::make_shared<MyObject>(10);
// катуу эсептегич: 1, слаб эсептегич: 0
{
std::shared_ptr<MyObject> ptr2 = ptr1;
// катуу эсептегич: 2, слаб эсептегич: 0
std::weak_ptr<MyObject> weak_ptr = ptr1;
// катуу эсептегич: 2, слаб эсептегич: 1
if (auto locked_ptr = weak_ptr.lock()) {
// катуу эсептегич: 3, слаб эсептегич: 1 (lock ичинде)
std::cout << "Объект маалыматтары: " << locked_ptr->data << std::endl;
}
// катуу эсептегич: 2, слаб эсептегич: 1
} // ptr2 аймактан чыгат
// катуу эсептегич: 1, слаб эсептегич: 1
// Объект дагы жок кылынган эмес, анткени катуу эсептегич 1
{
std::weak_ptr<MyObject> weak_ptr2 = ptr1;
// катуу эсептегич: 1, слаб эсептегич: 2
} // weak_ptr2 аймактан чыгат
// катуу эсептегич: 1, слаб эсептегич: 1
} // ptr1 аймактан чыгат
// катуу эсептегич: 0, слаб эсептегич: 1
// Объект жок кылынат, анткени катуу эсептегич 0 болду
// Башкаруу блогу калганча, слаб эсептегич 0 болбосо, калат