Middle
Šta znate o pametnim pokazivačima u C++?
sobes.tech АИ
Одговор од АИ
Pametni pokazivači - to su RAII omotači nad običnim (sirovim) pokazivačima u C++, koji pružaju automatsko upravljanje vremenom života alocirane memorije, sprečavajući curenje.
Glavne vrste pametnih pokazivača u standardnoj biblioteci C++:
std::unique_ptrstd::shared_ptrstd::weak_ptr
std::unique_ptr
- Ekskluzivno poseduje resurs.
- Ne može biti kopiran, ali može biti pomeren.
- Koristi se za jedinstveno vlasništvo nad resursom.
- Troškovi su minimalni, ekvivalentni sirovom pokazivaču.
// primer sa unique_ptr
#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; // Greška pri kompilaciji: unique_ptr se ne kopira
std::unique_ptr<int> ptr3 = std::move(ptr); // Premestanje vlasništva
std::cout << *ptr3 << std::endl; // 10
// std::cout << *ptr << std::endl; // Nedefinisano ponašanje: ptr je sada prazan
return 0;
}
std::shared_ptr
- Omogućava više pokazivača da zajednički poseduje jedan resurs.
- Koristi brojač referenci. Memorija se oslobađa kada brojač dostigne nulu.
- Može biti kopiran. Svaka kopija povećava brojač.
- Ima veće troškove u poređenju sa
unique_ptrzbog upravljanja brojačem.
// primer sa shared_ptr
#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; // Kopiranje, povećava use_count
std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 2)
std::shared_ptr<int> ptr3 = ptr1; // Još jedna kopija
std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 3)
return 0;
}
std::weak_ptr
- Ne poseduje resurs i ne povećava brojač.
- Koristi se za rešavanje problema cikličnih referenci između
shared_ptr. - Omogućava pristup resursu na koji ukazuje
shared_ptr, ali ne sprečava njegovo brisanje. - Za pristup resursu, potrebno je konvertovati
weak_ptrushared_ptrpomoću metodelock().
// primer sa weak_ptr
#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 << "Resurs je već oslobođen." << std::endl;
}
shared_ptr_int.reset(); // Resurs se oslobađa
if (auto locked_ptr = weak_ptr_int.lock()) {
std::cout << *locked_ptr << std::endl;
} else {
std::cout << "Resurs je već oslobođen." << std::endl; // Resurs je već oslobođen
}
return 0;
}
Korišćenje pametnih pokazivača je dobra praksa u savremenom C++, jer značajno smanjuje verovatnoću grešaka u upravljanju memorijom.