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 {
// Օբյեկտը արդեն հեռացվել է
}
}