Middle
Wat weet je over smart pointers in C++?
sobes.tech AI
Antwoord van AI
Slimme pointers zijn RAII-wrappers over gewone (ruwe) pointers in C++, die automatische geheugenbeheer bieden en geheugenlekken voorkomen.
De belangrijkste typen slimme pointers in de standaardbibliotheek van C++:
std::unique_ptrstd::shared_ptrstd::weak_ptr
std::unique_ptr
- Bezit de resource exclusief.
- Kan niet worden gekopieerd, maar wel worden verplaatst.
- Wordt gebruikt voor het exclusieve eigendom van de resource.
- De overhead is minimaal, gelijk aan die van een ruwe pointer.
// voorbeeld van 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; // Fout bij compilatie: unique_ptr kan niet worden gekopieerd
std::unique_ptr<int> ptr3 = std::move(ptr); // Verplaats eigendom
std::cout << *ptr3 << std::endl; // 10
// std::cout << *ptr << std::endl; // Onbepaald gedrag: ptr is nu leeg
return 0;
}
std::shared_ptr
- Laat meerdere pointers toe om gezamenlijk een resource te bezitten.
- Gebruikt een referentieteller. Het geheugen wordt vrijgegeven wanneer de teller op nul staat.
- Kan worden gekopieerd. Elke kopie verhoogt de teller.
- Heeft hogere overhead dan
unique_ptrvanwege het beheer van de teller.
// voorbeeld van 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; // Kopie, verhoogt use_count
std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 2)
std::shared_ptr<int> ptr3 = ptr1; // Nog een kopie
std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 3)
return 0;
}
std::weak_ptr
- Bezit de resource niet en verhoogt de teller niet.
- Wordt gebruikt om het probleem van cyclische referenties tussen
shared_ptrop te lossen. - Biedt toegang tot de resource waarnaar
shared_ptrwijst, maar voorkomt niet dat deze wordt verwijderd. - Om toegang te krijgen tot de resource, moet
weak_ptrworden geconverteerd naarshared_ptrmet behulp van delock()-methode.
// voorbeeld van 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 << "Resource is vrijgegeven." << std::endl;
}
shared_ptr_int.reset(); // Resource wordt vrijgegeven
if (auto locked_ptr = weak_ptr_int.lock()) {
std::cout << *locked_ptr << std::endl;
} else {
std::cout << "Resource is vrijgegeven." << std::endl; // Resource is vrijgegeven.
}
return 0;
}
Het gebruik van slimme pointers is een goede praktijk in moderne C++, omdat het de kans op geheugenfouten aanzienlijk vermindert.