Here's an example which shows two different ways of getting a shared_ptr from a weak_ptr:
#include <memory>
#include <iostream>
void print_shared1(std::weak_ptr <int> wp)
{
// always gets pointer safely
std::shared_ptr <int> sp(wp.lock());
std::cout << "wp = " << (sp ? *sp : 0) << std::endl;
}
void print_shared2(std::weak_ptr <int> wp)
{
// can crash if pointer has been freed
std::shared_ptr <int> sp(wp);
std::cout << "wp = " << (sp ? *sp : 0) << std::endl;
}
int main(int argc, char* argv[])
{
std::shared_ptr <int> s = std::make_shared<int>(1);
std::weak_ptr <int> w = s;
print_shared1(w);
print_shared2(w);
s.reset();
print_shared1(w);
print_shared2(w);
}
When it is run, this is the output:
wp = 1
wp = 1
wp = 0
terminate called after throwing an instance of 'std::bad_weak_ptr'
what(): bad_weak_ptr
Aborted (core dumped)
Clearly it is not always safe to access a weak pointer simply by constructing a shared pointer from it.
My questions are:
- In the function print_shared2, why are the semantics of wp.lock() not used during the construction of sp?
- Of what use is std::bad_weak_ptr at all?
You just saw the use of it.
lockreturns an emptyshared_ptr; the constructor throws an exception.Using the
shared_ptrconstructor means "I am certain that thisweak_ptris valid, and if it isn't, that is an exceptional error condition that must be handled immediately." If you are uncertain of the status of theweak_ptrand want to check it, uselock.