Achtergrond:
Gewone (raw) pointers zijn de traditionele manier in C++ om met dynamisch geheugen te werken. Dit is een universele abstracte mechanism, maar helaas is het erg vatbaar voor fouten: geheugenlekken, dubbele verwijderingen, en dangling pointers. Daarom omvat de standaardbibliotheek met C++11 slimme pointers — sjabloonklassen (std::unique_ptr, std::shared_ptr, std::weak_ptr) die automatisch het levenscyclusbeheer van een object regelen.
Probleem:
Bij het gebruik van gewone pointers ligt de verantwoordelijkheid voor het toewijzen en vrijgeven van geheugen bij de programmeur. Fouten in het vrijgeven van geheugen leiden tot lekken (memory leaks), dataverlies en crashes van programma's. Vooral complexe gevallen komen voor bij het afhandelen van uitzonderingen of bij het doorgeven van pointers aan andere functies.
Oplossing:
Slimme pointers encapsuleren het toegewezen geheugen en geven het automatisch vrij wanneer er geen eigenaren meer zijn. Ze implementeren RAII. std::unique_ptr biedt exclusief eigendom, std::shared_ptr — gedeeld eigendom, std::weak_ptr — niet-beheerend (om "cyclus verwijzingen" te voorkomen).
Codevoorbeeld:
#include <memory> void foo() { std::unique_ptr<int> p = std::make_unique<int>(5); // geheugen wordt vrijgegeven, zelfs bij uitzondering // ... }
Belangrijke kenmerken:
Kan std::unique_ptr worden gebruikt in een array gemaakt met new[]?
Nee, voor arrays gebruik std::unique_ptr<T[]>: zo zal delete[] worden aangeroepen in plaats van delete.
std::unique_ptr<int[]> arr(new int[10]);
Kunnen standaard slimme pointers alle mogelijke geheugenlekken voorkomen?
Nee. Bijvoorbeeld, cyclische verwijzingen tussen std::shared_ptr leiden tot lekken. Voor het doorbreken van dergelijke cycli gebruik je std::weak_ptr.
Kunnen slimme pointers hetzelfde object twee keer "verwijderen"?
Nee, tenzij je de eigendomslogica schendt (gebruik geen raw pointers!). Als je handmatig een raw pointer kopieert, kan vernietiging twee keer plaatsvinden.
Er worden rauwe pointers gebruikt, geheugen wordt handmatig vrijgegeven, bij het gooien van een uitzondering wordt het geheugen niet vrijgegeven.
Voordelen:
Nadelen:
Er wordt gebruikgemaakt van std::unique_ptr en std::make_unique voor het creëren van objecten en het doorgeven aan functies.
Voordelen:
Nadelen: