Middle
259
std::shared_ptr-дағы сілтеме санагыш қалай жұмыс істейді?
AI-дан жауап
sobes.tech AI
std::shared_ptr-тағы сілтеме есептегіш бөлек басқару блогында сақталады.
Басқару блогы құрылады:
std::shared_ptrкөрсеткішінен алғаш рет жасалғанда.- Пайдаланушының жоюшысы немесе аллокаторы бар
std::shared_ptrжасалғанда. std::make_sharedнемесеstd::allocate_sharedқолданғанда.
Бұл басқару блогында кемінде екі есептегіш бар:
- Қатты сілтемелер есептегіші (strong count):
std::shared_ptrжасалғанда немесе көшірілгенде өседі.std::shared_ptrжойылғанда кемиді. Бұл есептегіш нөлге айналғанда басқарылатын объекті босатылады. - Әлсіз сілтемелер есептегіші (weak count):
std::shared_ptr-данstd::weak_ptrжасалғанда өседі.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-ге айналғанша қалады