რის საფუძველზე რამდენიმე 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 მიუთითებს ერთსა და იმავე კონტროლ ბლოკზე, რომელიც აკონტროლებს მათი მფლობელობების რაოდენობას და განსაზღვრავს მართვად რესურსის განთავისუფლების მომენტს.