Sobes.tech
Middle

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