Sobes.tech
Middle

Ką žinote apie išmaniuosius rodyklius C++?

sobes.tech AI

Atsakymas iš AI

Protingi rodykliai - tai RAII apvalkalai virš įprastų (žalių) rodyklių C++ kalboje, kurie suteikia automatinį atminties gyvavimo laiko valdymą, užkertant kelią atminties nutekėjimams.

Pagrindiniai C++ standartinės bibliotekos tipai:

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

std::unique_ptr

  • Valdo išskirtinį išteklių.
  • Negali būti kopijuojamas, bet gali būti perkeliamas.
  • Naudojamas vieninteliam išteklių valdymui.
  • Maži papildomi kaštai, lygūs žaliam rodykliui.
// unikalus rodyklio pavyzdys
#include <memory>
#include <iostream>

int main() {
    std::unique_ptr<int> ptr = std::make_unique<int>(10);
    std::cout << *ptr << std::endl; // 10
    // std::unique_ptr<int> ptr2 = ptr; // Kompiliacijos klaida: unique_ptr nekopijuojamas
    std::unique_ptr<int> ptr3 = std::move(ptr); // Perkėlimas
    std::cout << *ptr3 << std::endl; // 10
    // std::cout << *ptr << std::endl; // Nenumatyta elgsena: ptr dabar tuščias
    return 0;
}

std::shared_ptr

  • Leidžia keliems rodykliams bendrą turtą.
  • Naudoja nuorodų skaitiklį. Atmintis atlaisvinama, kai skaitiklis pasiekia nulį.
  • Gali būti kopijuojamas. Kiekviena kopija didina skaitiklį.
  • Dideli papildomi kaštai, palyginti su unique_ptr, dėl skaitiklio valdymo.
// bendras rodyklio pavyzdys
#include <memory>
#include <iostream>

int main() {
    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; // kopijavimas, didina use_count
    std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 2)
    std::shared_ptr<int> ptr3 = ptr1; // dar viena kopija
    std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 3)
    return 0;
}

std::weak_ptr

  • Nevaldo išteklių ir nepadidina skaitiklio.
  • Naudojamas ciklinių nuorodų tarp shared_ptr sprendimui.
  • Leidžia pasiekti turtą, kurį rodo shared_ptr, bet neapsaugo nuo jo ištrynimo.
  • Norint pasiekti turtą, weak_ptr turi būti konvertuotas į shared_ptr naudojant lock() metodą.
// weak_ptr pavyzdys
#include <memory>
#include <iostream>

int main() {
    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 << "Išteklius jau pašalintas." << std::endl;
    }

    shared_ptr_int.reset(); // Išteklis išlaisvinamas

    if (auto locked_ptr = weak_ptr_int.lock()) {
        std::cout << *locked_ptr << std::endl;
    } else {
        std::cout << "Išteklius jau pašalintas." << std::endl; // Išteklis jau pašalintas
    }
    return 0;
}

Naudojant išmaniuosius rodyklius, tai yra gera praktika šiuolaikinėje C++, nes tai žymiai sumažina klaidų tikimybę valdant atmintį.