Smart Pointers: Weak Pointers using lock()
Method
What is it?
A Weak Pointer is a part of C++ Smart Pointers that holds a non-owning reference to an object managed by a std::shared_ptr
. It is used to track an object, but it allows the object to be deleted when it's no longer used.
The lock()
method is used to create a shared_ptr that shares ownership of the managed object (if it exists). If the managed object has been deleted (which means, it does not exist), then it would return an empty shared_ptr.
Syntax
The syntax for using std::weak_ptr::lock()
method is:
std::shared_ptr<T> lock() const noexcept;
Where,
T
is the type of the object that is being pointed bystd::weak_ptr
.
How to use it
To use the lock()
method, follow the below steps:
- Create a
std::shared_ptr
and initialize it with an object. - Create a
std::weak_ptr
from the shared_ptr. - Use the
lock()
method to get astd::shared_ptr
to the object if it exists.
Program code snippet example
#include <iostream>
#include <memory>
using namespace std;
int main() {
// Creating a shared_ptr and initializing it with an integer.
shared_ptr<int> myShared = make_shared<int>(10);
// Creating a weak_ptr from the shared_ptr.
weak_ptr<int> myWeak = myShared;
{
// Locking the weak_ptr to get a shared_ptr to the object.
shared_ptr<int> myLocked = myWeak.lock();
// If the object still exists, print it.
if(myLocked) {
cout << "Object exists: " << *myLocked << endl;
} else {
cout << "Object has been deleted!" << endl;
}
}
// Deleting the object managed by the shared_ptr.
myShared.reset();
{
// Trying to lock the weak_ptr again.
shared_ptr<int> myLocked = myWeak.lock();
// If the object still exists, print it.
if(myLocked) {
cout << "Object exists: " << *myLocked << endl;
} else {
cout << "Object has been deleted!" << endl;
}
}
return 0;
}
Output:
Object exists: 10
Object has been deleted!
Important to know
std::weak_ptr
does not extend the lifetime of the managed object. The object could be deleted while it's being pointed to by astd::weak_ptr
.std::weak_ptr::lock()
method is used to check whether the object exists before accessing it.std::weak_ptr
is designed to help eliminate the problem of dangling pointers and cyclic references that can lead to memory leaks.
Best practices
When using std::weak_ptr::lock()
, it is important to keep the following best practices in mind:
Use
std::weak_ptr
to prevent cyclic references: If you have objects that reference each other in a cyclic way (for example, in a parent-child relationship where the parent has astd::shared_ptr
to the child, and the child has astd::shared_ptr
to the parent), use astd::weak_ptr
for one of the pointers to break the cycle.Always check the existence of the object before accessing it: Before accessing the object pointed to by a
std::weak_ptr
, always check
whether it exists by calling the lock()
method and checking the returned std::shared_ptr
.
- Avoid using
std::weak_ptr
if not necessary: The use ofstd::weak_ptr
adds complexity to the code. If you don't have cyclic references or dangling pointers problem, prefer usingstd::shared_ptr
.
Call the lock()
member function from the weak pointer, boss_ptr2
. Then call the attack()
method of the shared pointer object of Boss
class.