Menu
Coddy logo textTech

Inteligentne wskaźniki w C++

Część sekcji Programowanie obiektowe ścieżki C++ w Coddy. Lekcja 15 z 104.

Inteligentne wskaźniki to klasy opakowujące, które automatycznie zarządzają pamięcią sterty. Eliminują potrzebę ręcznego wywoływania delete, zwalniając pamięć, gdy wskaźnik wyjdzie poza zakres.

Do korzystania z inteligentnych wskaźników dołącz nagłówek <memory>.

unique_ptr — wyłączne posiadanie. Tylko jeden wskaźnik może w danej chwili posiadać zasób.

#include <memory>

std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack();  // Używaj jak zwykłego wskaźnika

// Nie można kopiować, ale można przenieść własność
std::unique_ptr<Player> player2 = std::move(player);
// player ma teraz wartość nullptr

shared_ptr — współdzielone posiadanie. Wiele wskaźników może posiadać ten sam zasób. Pamięć jest zwalniana, gdy zostanie zniszczony ostatni właściciel.

std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1;  // Oba są właścicielami zasobu

std::cout << p1.use_count();  // Wypisuje 2

weak_ptr — nieposiadający obserwator obiektu shared_ptr. Przydatny do przerywania cyklicznych odwołań.

std::shared_ptr<Player> shared = std::make_shared<Player>("Hero");
std::weak_ptr<Player> weak = shared;

if (auto locked = weak.lock()) {  // Konwertuj na shared_ptr
    locked->attack();
}

Domyślnie używaj unique_ptr do wyłącznego posiadania. Używaj shared_ptr, gdy wiele obiektów musi współdzielić zasób. Używaj weak_ptr, aby obserwować bez przedłużania czasu życia.

Wybieraj make_unique i make_shared zamiast surowego new.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system udostępniania dokumentów, który demonstruje różne modele własności inteligentnych wskaźników. Zobaczysz, jak unique_ptr wymusza wyłączną własność, jak shared_ptr umożliwia współdzielenie własności przez wielu właścicieli oraz jak weak_ptr może obserwować obiekt bez wpływu na czas jego życia.

Utworzysz dwa pliki, aby uporządkować swój kod:

  • Document.h: Zdefiniuj klasę Document, która reprezentuje udostępniany dokument. Powinna zawierać:
    • Prywatny atrybut title (string)
    • Konstruktor, który przyjmuje tytuł i wyświetla "Document created: <title>"
    • Destruktor, który wyświetla "Document deleted: <title>"
    • Metodę getTitle(), która zwraca tytuł
  • main.cpp: Zademonstruj wszystkie trzy typy inteligentnych wskaźników, odczytując tytuł dokumentu z wejścia, a następnie:
    • Utwórz unique_ptr wskazujący na dokument z podanym tytułem
    • Wyświetl "Unique owner: <title>"
    • Przenieś własność na inny unique_ptr, używając std::move
    • Wyświetl "Ownership transferred"
    • Utwórz shared_ptr wskazujący na nowy dokument o tytule "SharedDoc"
    • Utwórz drugi shared_ptr wskazujący na ten sam dokument
    • Wyświetl "Shared owners: <count>", używając use_count()
    • Utwórz weak_ptr na podstawie jednego ze współdzielonych wskaźników
    • Użyj lock(), aby uzyskać dostęp do dokumentu za pośrednictwem słabego wskaźnika, i wyświetl "Weak access: <title>"

Pamiętaj, aby dołączyć <memory>, aby korzystać z inteligentnych wskaźników. Użyj std::make_unique i std::make_shared, aby utworzyć inteligentne wskaźniki. Komunikaty z destruktora pomogą ci zobaczyć, kiedy każdy dokument jest automatycznie usuwany po zakończeniu działania programu.

Dołącz plik nagłówkowy w main.cpp, używając #include "Document.h".

Spróbuj swoich sił

#include <iostream>
#include <memory>
#include <string>
#include "Document.h"

using namespace std;

int main() {
    string inputTitle;
    cin >> inputTitle;

    // TODO: Utwórz unique_ptr do Document z inputTitle
    // używając std::make_unique

    // TODO: Wypisz "Unique owner: <title>"

    // TODO: Przenieś własność do innego unique_ptr za pomocą std::move

    // TODO: Wypisz "Ownership transferred"

    // TODO: Utwórz shared_ptr do nowego Document o tytule "SharedDoc"
    // używając std::make_shared

    // TODO: Utwórz drugi shared_ptr wskazujący na ten sam dokument

    // TODO: Wypisz "Shared owners: <count>" za pomocą use_count()

    // TODO: Utwórz weak_ptr na podstawie jednego ze wskaźników współdzielonych

    // TODO: Użyj lock(), aby uzyskać dostęp do dokumentu przez weak_ptr
    // i wypisz "Weak access: <title>"

    return 0;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C++ online