Sobes.tech
Middle

Ko jūs zināt par gudrajiem rādītājiem C++?

sobes.tech AI

Atbilde no AI

Gudrie norādes ir RAII-apvalki pār parastiem (neapstrādātiem) norādītājiem C++ un nodrošina automātisku atmiņas resursu dzīvības cikla pārvaldību, novēršot noplūdes.

Galvenie standarta bibliotēkas C++ veidi:

  • std::unique_ptr
  • std::shared_ptr
  • std::weak_ptr

std::unique_ptr

  • Ekskluzīvi pārvalda resursu.
  • Nav kopējams, bet var tikt pārvietots.
  • Izmanto resursa unikālai īpašumtiesībai.
  • Papildu izmaksas ir minimālas, līdzīgas neapstrādātam norādītājam.
// unique_ptr piemērs
#include <memory>
#include <iostream>

int galvenais() {
    std::unique_ptr<int> ptr = std::make_unique<int>(10);
    std::cout << *ptr << std::endl; // 10
    // std::unique_ptr<int> ptr2 = ptr; // Kompilācijas kļūda: unique_ptr netiek kopēts
    std::unique_ptr<int> ptr3 = std::move(ptr); // Pārvietošana
    std::cout << *ptr3 << std::endl; // 10
    // std::cout << *ptr << std::endl; // Neapstrādāta uzvedība: ptr tagad ir tukšs
    return 0;
}

std::shared_ptr

  • Atļauj vairākiem norādītājiem kopīgi piederēt vienam resursam.
  • Izmanto atsauces skaitītāju. Atbrīvo atmiņu, kad skaitītājs sasniedz nulli.
  • Var tikt kopēts. Katrs kopējums palielina skaitītāju.
  • Ir lielākas papildu izmaksas nekā unique_ptr dēļ skaitītāja uzturēšanas.
// shared_ptr piemērs
#include <memory>
#include <iostream>

int galvenais() {
    std::shared_ptr<int> ptr1 = std::make_shared<int>(20);
    std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 1)
    std::shared_ptr<int> ptr2 = ptr1; // Kopēšana, palielina use_count
    std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 2)
    std::shared_ptr<int> ptr3 = ptr1; // Vēl viena kopija
    std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 3)
    return 0;
}

std::weak_ptr

  • Nepieder resursam un nepalielina skaitītāju.
  • Izmanto, lai risinātu cikliskas atsauces starp shared_ptr.
  • Atļauj piekļūt resursam, uz kuru norāda shared_ptr, bet neizslēdz tā dzēšanu.
  • Lai piekļūtu resursam, nepieciešams pārveidot weak_ptr uz shared_ptr ar lock() metodi.
// weak_ptr piemērs
#include <memory>
#include <iostream>

int galvenais() {
    std::shared_ptr<int> shared_ptr_int = std::make_shared<int>(30);
    std::weak_ptr<int> weak_ptr_int = shared_ptr_int;

    if (auto locked_ptr = weak_ptr_int.lock()) {
        std::cout << *locked_ptr << std::endl; // 30
    } else {
        std::cout << "Resurss ir atbrīvots." << std::endl;
    }

    shared_ptr_int.reset(); // Resurss tiek atbrīvots

    if (auto locked_ptr = weak_ptr_int.lock()) {
        std::cout << *locked_ptr << std::endl;
    } else {
        std::cout << "Resurss ir atbrīvots." << std::endl; // Resurss ir atbrīvots.
    }
    return 0;
}

Izmantošana gudriem norādītājiem ir laba prakse mūsdienu C++, jo ievērojami samazina atmiņas pārvaldības kļūdu iespējamību.