Sobes.tech
Junior

Кои умни указатели (smart pointers) знаете?

sobes.tech AI

Отговор от AI

std::unique_ptr, std::shared_ptr, std::weak_ptr, std::auto_ptr (остарял в C++11 и премахнат в C++17).

  • std::unique_ptr: Ексклузивно притежание на ресурса. Ресурсът се освобождава, когато указателят излезе извън обхвата или бъде нулиран. Не позволява копиране, само преместване.

    #include <memory>
    
    int main() {
        std::unique_ptr<int> ptr(new int(5));
        // std::unique_ptr<int> ptr2 = ptr; // Грешка: не може да се копира
        std::unique_ptr<int> ptr3 = std::move(ptr); // Преместване
        return 0;
    }
    
  • std::shared_ptr: Общ собственик на ресурса. Използва брояч на препратки. Ресурсът се освобождава, когато последният shared_ptr, който сочи към него, излезе извън обхвата или бъде нулиран. Поддържа копиране.

    #include <memory>
    
    int main() {
        std::shared_ptr<int> ptr1(new int(10));
        std::shared_ptr<int> ptr2 = ptr1; // Копиране, броячът се увеличава
        return 0;
    }
    
  • std::weak_ptr: Не притежава ресурса и не увеличава брояча на препратките на shared_ptr. Използва се за предотвратяване на циклични препратки между shared_ptr. За достъп до ресурса се получава shared_ptr чрез метода lock().

    #include <memory>
    
    int main() {
        std::shared_ptr<int> shared_ptr_inst(new int(20));
        std::weak_ptr<int> weak_ptr_inst = shared_ptr_inst; // Създаване на weak_ptr
    
        if (auto locked_ptr = weak_ptr_inst.lock()) {
            // Успешно получен `shared_ptr`, може да се използва ресурсът
        } else {
            // Ресурсът вече е освободен
        }
        return 0;
    }
    
  • std::auto_ptr: Застарял интелигентен указател с семантика на собственост при копиране, което водеше до неочаквано поведение. Не трябва да се използва в новия код.

Разлики между shared_ptr и weak_ptr:

Характеристика std::shared_ptr std::weak_ptr
Собственост на ресурса Да Не
Брояч на препратки Увеличава Не увеличава
Освобождаване на ресурс Да, когато броячът е 0 Не
Циклични препратки Могат да причинят проблеми Помага да се предотвратят
Достъп до ресурса Пряко чрез operator*, operator-> Чрез метода lock()