Middle
Чӣ тавр ҳисобкунаки истинод дар std::shared_ptr кор мекунад?
sobes.tech AI
Ҷавоб аз AI
Шумораи истинодҳо дар std::shared_ptr дар объекти алоҳида нигоҳ дошта мешавад — блоки идоракунӣ (control block).
Блоки идоракунӣ сохта мешавад:
- Дар аввалин бор, вақте ки
std::shared_ptrаз нишондиҳанда сохта мешавад. - Вақте ки
std::shared_ptrбо тозакунанда ё аллокатори корбар сохта мешавад. - Вақте ки
std::make_sharedёstd::allocate_sharedистифода мешавад.
Ин блоки идоракунӣ ҳадди ақал ду ҳисобкунак дорад:
- Ҳисобкунаки пайвандҳои қавӣ (strong count): Вақте ки
std::shared_ptrсохта ё нусхабардорӣ мешавад, зиёд мешавад. Вақте киstd::shared_ptrнест карда мешавад, кам мешавад. Вақте ки ин ҳисобкунак ба сифр мерасад, объекти идорашаванда озод мешавад. - Ҳисобкунаки пайвандҳои заъиф (weak count): Вақте ки
std::weak_ptrазstd::shared_ptrсохта мешавад, зиёд мешавад. Вақте киstd::weak_ptrнест карда мешавад, кам мешавад. Блоки идоракунӣ озод мешавад, вақте ки ҳарду ҳисобкунак — қавӣ ва заъиф — ба сифр мерасанд.
Истифодаи std::make_shared афзалтар аст аз сохтани мустақим бо new, зеро он метавонад объект ва блоки идоракунӣ дар як минтақаи хотира алоқаманд созад, ки ин ба иҷроиш беҳтар ва камтар фрагментацияро таъмин мекунад.
Атомик ҳисобкунакҳо std::shared_ptr-ро бехатар барои истифода дар муҳити бисёрсоҳавӣ месозанд, ҳарчанд дастрасӣ ба объекти идорашаванда ба таври пешфарз синхрон карда нашудааст.
Масалан:
#include <iostream>
#include <memory>
struct MyObject {
int data;
MyObject(int d) : data(d) {
std::cout << "MyObject(" << data << ") created\n";
}
~MyObject() {
std::cout << "MyObject(" << data << ") destroyed\n";
}
};
int main() {
std::shared_ptr<MyObject> ptr1 = std::make_shared<MyObject>(10);
// ҳисобкунаки қавӣ: 1, ҳисобкунаки заъиф: 0
{
std::shared_ptr<MyObject> ptr2 = ptr1;
// ҳисобкунаки қавӣ: 2, ҳисобкунаки заъиф: 0
std::weak_ptr<MyObject> weak_ptr = ptr1;
// ҳисобкунаки қавӣ: 2, ҳисобкунаки заъиф: 1
if (auto locked_ptr = weak_ptr.lock()) {
// ҳисобкунаки қавӣ: 3, ҳисобкунаки заъиф: 1 (дар дохили lock)
std::cout << "Object data: " << locked_ptr->data << std::endl;
}
// ҳисобкунаки қавӣ: 2, ҳисобкунаки заъиф: 1
} // ptr2 аз минтақа мебарояд
// ҳисобкунаки қавӣ: 1, ҳисобкунаки заъиф: 1
// Объект ҳанӯз нест шудааст, зеро ҳисобкунаки қавӣ == 1
{
std::weak_ptr<MyObject> weak_ptr2 = ptr1;
// ҳисобкунаки қавӣ: 1, ҳисобкунаки заъиф: 2
} // weak_ptr2 аз минтақа мебарояд
// ҳисобкунаки қавӣ: 1, ҳисобкунаки заъиф: 1
} // ptr1 аз минтақа мебарояд
// ҳисобкунаки қавӣ: 0, ҳисобкунаки заъиф: 1
// Объект нест карда мешавад, зеро ҳисобкунаки қавӣ ба сифр расид
// Блоки идоракунӣ то вақте ки ҳисобкунаки заъиф ба сифр нарасад, боқӣ мемонад