Show Lecture.SmartPointers as a slide show.
delete
the memory.
delete
the memory,
an exception might prevent that from happening.
#include "Loud.h" int main(int argc, char **) { auto p = new Loud; if (argc < 5) { cerr << "Not enough arguments.\n"; return 1; } delete p; return 0; }
Loud::Loud() Not enough arguments.
Repeat to yourself, “It’s just an example, I should really just relax.”
delete p
, but that violates DRY.
unique_ptr
if the thing has one owner
shared_ptr
if the thing has several owners
weak_ptr
for voyeurs & lurkers
auto_ptr
for people who use obsolete features
auto_ptr
.
auto_ptr
was deprecated in C++2011
auto_ptr
was removed from C++2017.
unique_ptr
unique_ptr
is built-in RAII.
unique_ptr
“owns” the pointed-to object.
unique_ptr
is destroyed (usually, by falling out of scope)
then the pointed-to objected is destroyed, as well.
unique_ptr
. Which one would be the unique owner?
unique_ptr
example #1#include "Loud.h" int main(int argc, char **) { unique_ptr<Loud> p(new Loud); if (argc < 5) { cerr << "Not enough arguments.\n"; return 1; } // don’t need to delete return 0; }
Loud::Loud() Not enough arguments. Loud::~Loud()
#include "Loud.h" void foo() { unique_ptr<Loud> p(new Loud); throw "I am unhappy"; } int main() { try { foo(); } catch (const char *p) { cerr << p << '\n'; } return 0; }
Loud::Loud() Loud::~Loud() I am unhappy
shared_ptr
is built-in RAII.
shared_ptr
is a “counting pointer”. It keeps track of how many
shared owners this object has, via a counter.
shared_ptr
. It just increments the use count.
shared_ptr
example#include "Loud.h" int main() { shared_ptr<Loud> p(new Loud); cout << p.use_count() << '\n'; { cout << p.use_count() << '\n'; auto q=p; cout << p.use_count() << '\n'; cout << q.use_count() << '\n'; } cout << p.use_count() << '\n'; }
Loud::Loud() 1 1 2 2 1 Loud::~Loud()
unique_ptr
, there’s only a single owner.
When the owner is destroyed, the dynamic object is destroyed.
shared_ptr
, there are multiple owners.
If any of the owners are destroyed, the shared object still exists,
as long as any owners remain.
weak_ptr
example#include <iostream> #include <memory> using namespace std; weak_ptr<int> wp; void observe() { cout << "use_count=" << wp.use_count() << ": "; if (auto sp = wp.lock()) cout << *sp << '\n'; else cout << "wp is expired\n"; } int main() { { shared_ptr<int> mem(new int(42)); wp = mem; observe(); } observe(); }
use_count=1: 42 use_count=0: wp is expired
weak_ptr
: why?weak_ptr
?
shared_ptr
to cached data,
then it would never get freed, because you own it.
This way, you can use it if it’s still around.