Sobes.tech
Junior

Jakie znasz inteligentne wskaźniki (smart pointers)?

sobes.tech AI

Odpowiedź od AI

std::unique_ptr, std::shared_ptr, std::weak_ptr, std::auto_ptr (zastąpione w C++11 i usunięte w C++17).

  • std::unique_ptr: Wyłączna własność zasobu. Zasób jest zwalniany, gdy wskaźnik wychodzi z zakresu lub jest resetowany. Nie pozwala na kopiowanie, tylko na przenoszenie.

    #include <memory>
    
    int main() {
        std::unique_ptr<int> ptr(new int(5));
        // std::unique_ptr<int> ptr2 = ptr; // Błąd: nie można kopiować
        std::unique_ptr<int> ptr3 = std::move(ptr); // Przenoszenie
        return 0;
    }
    
  • std::shared_ptr: Wspólne własność zasobu. Używa licznika odwołań. Zasób jest zwalniany, gdy ostatni shared_ptr wskazujący na niego wychodzi z zakresu lub jest resetowany. Obsługuje kopiowanie.

    #include <memory>
    
    int main() {
        std::shared_ptr<int> ptr1(new int(10));
        std::shared_ptr<int> ptr2 = ptr1; // Kopiowanie, licznik odwołań zwiększa się
        return 0;
    }
    
  • std::weak_ptr: Nie posiada zasobu i nie zwiększa licznika odwołań shared_ptr. Używany do zapobiegania cyklicznym odwołaniom między shared_ptr. Aby uzyskać dostęp do zasobu, należy uzyskać shared_ptr za pomocą metody 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; // Tworzenie weak_ptr
    
        if (auto locked_ptr = weak_ptr_inst.lock()) {
            // Pomyślnie uzyskano `shared_ptr`, można używać zasobu
        } else {
            // Zasób został już zwolniony
        }
        return 0;
    }
    
  • std::auto_ptr: Przestarzały inteligentny wskaźnik z semantyką własności przy kopiowaniu, co prowadziło do nieoczywistych zachowań. Nie należy go używać w nowym kodzie.

Różnice między shared_ptr a weak_ptr:

Cecha std::shared_ptr std::weak_ptr
Własność zasobu Tak Nie
Licznik odwołań Zwiększa Nie zwiększa
Zwolnienie zasobu Tak, gdy licznik = 0 Nie
Odwołania cykliczne Mogą powodować problemy Pomaga im zapobiegać
Dostęp do zasobu Bezpośrednio przez operator*, operator-> Przez metodę lock()