Ինչ հիմքով մի քանի shared_ptr օբյեկտներ կարող են հղում կատարել նույն ցուցիչին:
sobes.tech AI
Պատասխան AI-ից
Որոշ std::shared_ptr օբյեկտներ կարող են հղում ունենալ նույն ցուցիչին՝ շնորհիվ կառավարական բլոկի (control block) առկայության:
Կառավարական բլոկը, որը կապված է կառավարվող օբյեկտի հետ, պարունակում է.
- Հզոր հղումների հաշվիչ (strong reference count): Բարձրանում է, երբ ստեղծվում է նոր
shared_ptrնույն օբյեկտի համար: Կրճատվում է, երբshared_ptr-ը ոչնչացվում է: Երբ հասնում է զրոյի, կապված օբյեկտը (ցուցակը) ջնջվում է: - Թույլ հղումների հաշվիչ (weak reference count): Օգտագործվում է
std::weak_ptr-ի համար: Բարձրանում է, երբweak_ptr-ը ստեղծվում էshared_ptr-ից: Կրճատվում է, երբweak_ptr-ը ոչնչացվում է: Երբ երկու հաշվիչներն էլ զրոյին հասնեն, կառավարման բլոկը ջնջվում է: - Ինքնին ցուցիչ կառավարվող օբյեկտի վրա: Ոչ տվյալների ցուցիչը, այլ այն, որը կառավարում է բլոկը:
Երբ ստեղծում եք shared_ptr՝ գոյություն ունեցող shared_ptr-ից (կոպիա, նշանակում-կոպիա), նրանք սկսում են օգտագործել նույն կառավարման բլոկը, և ուժեղ հղումների հաշվիչը այդ բլոկում ավելանում է:
Օրինակ՝
#include <memory>
#include <iostream>
struct MyData {
int value;
MyData(int v) : value(v) { std::cout << "MyData(" << value << ") created.\n"; }
~MyData() { std::cout << "MyData(" << value << ") destroyed.\n"; }
};
int main() {
// Առաջին `shared_ptr`-ի ստեղծում:
// Կառավարական բլոկ և MyData օբյեկտ ստեղծվում են:
// ուժեղ հաշվիչը՝ 1, թույլ՝ 0:
std::shared_ptr<MyData> ptr1 = std::make_shared<MyData>(10);
std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";
// Երկրորդ `shared_ptr`-ի ստեղծում ptr1-ից:
// Օգտագործում է նույն կառավարման բլոկը:
// ուժեղ հաշվիչը՝ 2:
std::shared_ptr<MyData> ptr2 = ptr1;
std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";
std::cout << "ptr2 use count: " << ptr2.use_count() << "\n";
// Երրորդ `shared_ptr`-ի ստեղծում ptr1-ից:
// Օգտագործում է նույն կառավարման բլոկը:
// ուժեղ հաշվիչը՝ 3:
std::shared_ptr<MyData> ptr3 = ptr1;
std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";
std::cout << "ptr2 use count: " << ptr2.use_count() << "\n";
std::cout << "ptr3 use count: " << ptr3.use_count() << "\n";
std::cout << "Դուրս գալու սահմանից.\n";
// ptr3 դուրս է գալիս սահմանից:
// ուժեղ հաշվիչը՝ 2:
// ptr2 դուրս է գալիս սահմանից:
// ուժեղ հաշվիչը՝ 1:
// ptr1 դուրս է գալիս սահմանից:
// ուժեղ հաշվիչը՝ 0:
// MyData օբյեկտը ջնջվում է:
// Կառավարական բլոկը ջնջվում է:
}
Յուրաքանչյուր shared_ptr օբյեկտ ունի իր ցուցիչը կառավարման բլոկին և իր ցուցիչը տվյալների օբյեկտին: Երբ shared_ptr-ը կոպիա է, երկու ցուցիչներն էլ կոպիացվում են, և ուժեղ հղումների հաշվիչը մեծանում է ընդհանուր բլոկում: Այսպիսով, բոլոր shared_ptr-երը ցույց են տալիս նույն կառավարման բլոկին, որը հետևում է սեփականության օրինակների քանակին և որոշում է կառավարվող ռեսուրսի ազատման պահը։