Updated April 18, 2023
Introduction to C++ weak_ptr
C++ weak_ptr is part of the standard library, which is used to hold the weak reference to any object managed by another standard library pointer called shared_ptr, which means that the weak_ptr is used for it converting it finally to shared_ptr. The finally converted shared_ptr from weak_ptr is used to access the referenced object. Once a weak_ptr gets converted into shared_ptr, it loses its ability to stay permanently, which signifies that its existence is temporary. Accessing weak_ptr and then providing the ability for accessing the reference object is not a recommended way.
Syntax
template< class T > class weak_ptr;
The syntax flow for C++ weak_ptr is in a way where the parameter passed as Class T is used for the type controlled by the weak pointer.
How weak_ptr works in C++?
Every pointer in any high-level language is mostly used for object referencing and then accessing elements present in some organized format in an array. Similar is the case with weak_ptr in C++. The entire class template describes the working flow of weak_ptr :
- The weak_ptr used for referencing an object initially is not the actual pointer as it is considered as a temporary pointer in terms of object referencing and assigning.
- But once weak_ptr gets the final control or authority over the share_ptr, then it becomes easy and streamlined in terms of object accessing and referencing.
- This sharing and coordination, or say, switching between the weak_ptr and share_ptr for accessing and referencing, is mostly used for avoiding long cycles within the data structure.
- Weak_ptr loses all its control and gets deleted when the entire responsibility is taken by share_ptr at the time of allocation and analysis for managing resources.
- A weak_ptr never gives the ability to access the elements directly; rather, it makes use of the code that needs to use the resource through the shared_ptr object that owns the entire code by calling the member function called lock.
- An empty weak_ptr object gets created once the lock or the weak_ptr is called for resource allocation and for controlling any block.
- One entire cycle got completed or finished once the lock or the weak_ptr gets mutually referencing or hold by most of the shared_ptr object.
- It makes use of all resources prominently with the help of share_ptr rather than using the only weak_ptr, which is part of the entire working format of pointers in any of the pointer concepts.
- The behavior of the acquiring of locks and weak_ptr points to make the end resources freed and released by the weak_ptr, then shared_ptr with the release makes use of it.
- Once all the resources mentioned getting freed, then the list and its associated nodes will also get destroyed and differentiated easily, thus making an optimized way of analyzing and format sizing.
- There are many tests and methods which are part of this entire cycle, including the expired() method, which is used to test if ownership has expired or not.
- Lock() Is used to gain the exclusive and individual lock over the resource so that the other resource cannot target and get conflict while trying to acquire the resource.
- The owner () before is used to test for the weak_ptr pointing to return true if it points properly.
- Reset() is used for releasing the owned resource within that entire cycle.
- When two weak_ptr are acting on the objects, then it is called a swap() method.
- use_count() method is used for counting and tracking the number of shared_ptr objects.
- Operator= is the method that is used for replacing the initially owned resources.
Examples of C++ weak_ptr
Below are the examples of C++ weak_ptr:
Example #1
This program demonstrates the weak_ptr to be used as a constructor where the passed parameter as a constructor is used for acquiring the lock and giving the respective value as shown in the output.
Code:
#include <memory>
#include <iostream>
int main()
{
std::weak_ptr<int> wptr_0;
std::cout << "weak_ptr got expired " << std::boolalpha
<< wptr_0.expired() << std::endl;
std::shared_ptr<int> shrd_ptr1(new int(12));
std::weak_ptr<int> wptr_1(shrd_ptr1);
std::cout << "*wptr_1 acquired the_lock() == "
<< *wptr_1.lock() << std::endl;
std::weak_ptr<int> wptr_2(wptr_1);
std::cout << "*wptr_2 acquired the_lock() == "
<< *wptr_2.lock() << std::endl;
return (0);
}
Output:
Example #2
This program demonstrates the method owner_before, which explicitly, with the help of weak_ptr, tells about the value acquired using boolean value and then reset the value as earlier and gives the output as shown in the output.
Code:
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> shrd_ptr(new int(14));
std::weak_ptr<int> wk_ptr(shrd_ptr);
std::cout << "acquire weak_ptr in the lock: == " << *wk_ptr.lock() << std::endl;
std::cout << "weak_ptr got expired == " << std::boolalpha
<< wk_ptr.expired() << std::endl;
wk_ptr.reset();
std::cout << "After reset weak ptr fot expired*wk_ptr.lock()() == " << std::boolalpha
<< wk_ptr.expired() << std::endl;
return (0);
}
Output:
Example #3
This program demonstrates the count of the number of weak_ptr that is used for managing the order of the elements to access, as shown in the output.
Code:
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> shrd_ptr_1(new int(8));
std::weak_ptr<int> wk_ptr(shrd_ptr_1);
std::cout << "count the numner_of_weak_ptr : "
<< wk_ptr.use_count() << std::endl;
std::shared_ptr<int> shrd_ptr_2(shrd_ptr_1);
std::cout << "count the number_of_weak_ptr : "
<< wk_ptr.use_count() << std::endl;
return (0);
}
Output:
Example #4
This program demonstrates the swap() method used for swapping the weak_ptr when required to acquire the required resource, as shown in the output.
Code:
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> shrd_ptr_1(new int(8));
std::shared_ptr<int> shrd_ptr_2(new int(10));
std::cout << "*shrd_ptr_1 == " << *shrd_ptr_1 << std::endl;
shrd_ptr_1.swap(shrd_ptr_2);
std::cout << "*shrd_ptr_1 == " << *shrd_ptr_1 << std::endl;
swap(shrd_ptr_1, shrd_ptr_2);
std::cout << "*shrd_ptr_1 == " << *shrd_ptr_1 << std::endl;
std::cout << std::endl;
std::weak_ptr<int> wk_ptr_1(shrd_ptr_1);
std::weak_ptr<int> wk_ptr_2(shrd_ptr_2);
std::cout << "*wk_ptr_1 == " << *wk_ptr_1.lock() << std::endl;
wk_ptr_1.swap(wk_ptr_2);
std::cout << "*wk_ptr_2 == " << *wk_ptr_2.lock() << std::endl;
swap(wk_ptr_1, wk_ptr_2);
std::cout << "*wk_ptr_1 == " << *wk_ptr_1.lock() << std::endl;
return (0);
}
Output:
Conclusion
C++ weak_ptr plays a pivotal role in acquiring and accessing the elements within the node of the list. Also, shared_ptr with mutual coordination with weak_ptr helps in creating an optimized cycle for accessing the elements. Once shared_ptr has opted, then it Is mostly considered a permanent operation. C++ weak_ptr helps in many ways to acquire resources efficiently.
Recommended Articles
This is a guide to C++ weak_ptr. Here we discuss How weak_ptr works in C++ and Examples along with the codes and outputs. You can also look at the following article to learn more –