Sobes.tech
Senior

Ինչպես իրականացնել խելացի ցուցիչ մեկ կամ մի քանի օբյեկտների համար?

sobes.tech AI

Պատասխան AI-ից

Մի օբյեկտի համար՝ unique_ptr կամ shared_ptr: Բազմաթիվ օբյեկտների համար՝ shared_ptr (համատեղ սեփականություն) կամ weak_ptr (հետևում առանց կյանքի ցիկլի կառավարման մասնակցության):

#include <memory>
#include <vector>

// Օբյեկտի դասի օրինակ
class MyObject {
public:
    MyObject() { /* Կոնստրուկտոր */ }
    ~MyObject() { /* Դեստրուկտոր */ }
};

// Մի օբյեկտի համար՝ unique_ptr (միայնակ սեփականություն)
void single_unique_ptr() {
    std::unique_ptr<MyObject> ptr = std::make_unique<MyObject>();
    // Օբյեկտը ավտոմատորեն կչեղարկվի, երբ դուրս գա տեսանելիությունից
}

// Մի օբյեկտի համար՝ shared_ptr (համատեղ սեփականություն)
void single_shared_ptr() {
    std::shared_ptr<MyObject> ptr = std::make_shared<MyObject>();
    // Տիրապետողների թիվը ավելանում է
    std::shared_ptr<MyObject> another_ptr = ptr;
    // Օբյեկտը կչեղարկվի, երբ վերջին shared_ptr-ը կդադարի հղում ունենալ
}

// Բազմաթիվ օբյեկտների համար՝ վեկտորով shared_ptr-ներով
void multiple_shared_ptr() {
    std::vector<std::shared_ptr<MyObject>> objects;
    objects.push_back(std::make_shared<MyObject>());
    objects.push_back(std::make_shared<MyObject>());
    // Յուրաքանչյուր օբյեկտ կառավարվում է իր shared_ptr-ով վեկտորում
    // Օբյեկտները կչեղարկվեն, երբ համապատասխան shared_ptr-ները կչեղարկվեն
}

// Բազմաթիվ օբյեկտների համար՝ վեկտորով unique_ptr-ներով
void multiple_unique_ptr() {
    std::vector<std::unique_ptr<MyObject>> objects;
    objects.push_back(std::make_unique<MyObject>());
    objects.push_back(std::make_unique<MyObject>());
    // Այս դեպքում վեկտորը տիրապետում է յուրահատուկ ցուցանիշներին
    // Օբյեկտները կչեղարկվեն, երբ դուրս գան վեկտորի տեսանելիությունից

    // Նշում՝ unique_ptr-ները չեն կարող պատճենվել, միայն տեղափոխվել (move)
    std::unique_ptr<MyObject> moved_ptr = std::move(objects[0]);
}

unique_ptr և shared_ptr համեմատություն:

Գծագիր std::unique_ptr std::shared_ptr
Իշխանություն Միայնակ Մասամբ (հղումների հաշվիչ)
Կոպիա Ոչ (միայն տեղափոխում) Այո
Արդյունավետություն Փոքր-ինչ ավելի արագ (առանց հաշվիչի ավելցուկի) Փոքր-ինչ ավելի դանդաղ (հղումների հաշվիչ)
Ճկվող հղումներ Չի պաշտպանում Կարող է հանգեցնել հիշողության լքման (պահանջում է weak_ptr)

std::weak_ptr օգտագործվում է shared_ptr-ով կառավարվող օբյեկտին հետևելու համար, առանց ավելացնելու հղումների հաշվին, կանխելով ցիկլային հղումների խնդիրները:

#include <memory>

class Node {
public:
    std::shared_ptr<Node> next;
    std::weak_ptr<Node> previous; // օգտագործում է weak_ptr ցիկլային հղումներից խուսափելու համար

    Node() = default;
    ~Node() { /* Դեստրուկտոր */ }
};

void weak_ptr_example() {
    std::shared_ptr<Node> node1 = std::make_shared<Node>();
    std::shared_ptr<Node> node2 = std::make_shared<Node>();

    node1->next = node2;
    node2->previous = node1; // օգտագործում է weak_ptr

    // կարող է ստանալ shared_ptr-ով from weak_ptr
    if (std::shared_ptr<Node> locked_node = node2->previous.lock()) {
        // Եթե օբյեկտը դեռ կենդանի է
        // ... աշխատում ենք locked_node-ով
    } else {
        // Օբյեկտը արդեն հեռացվել է
    }
}