I am somewhat confused by the behaviour of the .lock()
call on a weak_ptr
. My understanding is that .lock()
will return a shared_ptr
of the relevant type if it has not expired otherwise it will be a null pointer.
From https://en.cppreference.com/w/cpp/memory/weak_ptr/lock :
A shared_ptr which shares ownership of the owned object if std::weak_ptr::expired returns false.
This is however not the outcome I am seeing. The code below is a method of the Unit
class that should return a shared_ptr
to the Unit
's parent:
unsigned Unit::getParentId() const {
auto parent = parent_.lock();
return parent->getId();
}
The debugger output below shows that parent_
exists as a weak_ptr
. However when I call auto parent = parent_.lock();
, it returns a NULL
pointer as can be seen in the last line of the debugger output.
I am obviously missing something really basic here?
this = {const Unit *} 0x16f1af010
id_ = {unsigned int} 234
name_ = {std::string} "Test"
parent_ = {std::weak_ptr<Unit>} std::__1::weak_ptr<Unit>::element_type @ 0x00006000034d00d8 strong=0 weak=2
__ptr_ = {std::weak_ptr<Unit>::element_type *} 0x6000034d00d8
id_ = {unsigned int} 0
name_ = {std::string} "Root"
parent_ = {std::weak_ptr<Unit>} nullptr
children_ = {std::vector<std::shared_ptr<Unit>>} size=0
children_ = {std::vector<std::shared_ptr<Unit>>} size=0
parent = {std::shared_ptr<Unit>} nullptr
__ptr_ = {std::shared_ptr<Unit>::element_type *} NULL
CodePudding user response:
Weak pointer attaches only to existing shared pointers, by itself weak pointer doesn't hold or create any object pointer. In other words if you do:
std::weak_ptr<int> wp;
auto sp = wp.lock();
then it always returns nullptr. You have to pass Existing shared pointer in constructor or through assignment (=
), e.g.
std::shared_ptr<int> sp = std::make_shared<int>();
std::weak_ptr<int> wp(sp);
auto spl = wp.lock(); // now spl is not null
or through assignment
std::shared_ptr<int> sp = std::make_shared<int>();
std::weak_ptr<int> wp;
wp = sp;
auto spl = wp.lock(); // now spl is not null
As long as all copies of shared pointer still exist then weak pointer will return non null on lock. Otherwise if no copies of shared pointer exist then weak pointer will always return null.
In your case you don't have any copies of shared pointers hence weak pointer will alway return null on lock in such case.