shared_ptr in C++
std::shared_ptr is one of the smart pointers introduced in C++11. Unlike a simple pointer, it has an associated control block that keeps track of the reference count for the managed object. This reference count is shared among all the copies of the shared_ptr instances pointing to the same object, ensuring proper memory management and deletion.
Prerequisites: Pointers in C++, Smart Pointers in C++.
Syntax of std::shared_ptr
The shared_ptr of type T can be declared as:
std::shared_ptr <T> ptr_name;
Initialization of shared_ptr Objects
We can initialize the shared_ptr using the following methods:
1. Initialization using a New Pointer
shared_ptr<T> ptr (new T());
shared_ptr<T> ptr = make_shared<T> (new T());
2. Initialization using existing Pointer
shared_ptr<T> ptr(already_existing_pointer);
shared_ptr<T> ptr = make_shared(already_existing_pointer);
Member Methods of shared_ptr
Following are some members associated with shared_ptr:
Method | Description |
---|---|
reset() | Resets the std::shared_ptr to empty, releasing ownership of the managed object. |
use_count() | Returns the current reference count, indicating how many std::shared_ptr instances share ownership. |
unique() | Check if there is only one std::shared_ptr owning the object (reference count is 1). |
get() | Returns a raw pointer to the managed object. Be cautious when using this method. |
swap(shr_ptr2) | swaps the contents (ownership) of two std::shared_ptr instances. |
Examples of std::shared_ptr
Example 1:
C++
// C++ program to demonstrate shared_ptr #include <iostream> #include <memory> using namespace std; class A { public : void show() { cout << "A::show()" << endl; } }; int main() { // creating a shared pointer and accessing the object shared_ptr<A> p1( new A); // printting the address of the managed object cout << p1.get() << endl; p1->show(); // creating a new shared pointer that shares ownership shared_ptr<A> p2(p1); p2->show(); // printing addresses of P1 and P2 cout << p1.get() << endl; cout << p2.get() << endl; // Returns the number of shared_ptr objects // referring to the same managed object. cout << p1.use_count() << endl; cout << p2.use_count() << endl; // Relinquishes ownership of p1 on the object // and pointer becomes NULL p1.reset(); cout << p1.get() << endl; cout << p2.use_count() << endl; cout << p2.get() << endl; /* These lines demonstrate that p1 no longer manages an object (get() returns nullptr), but p2 still manages the same object, so its reference count is 1. */ return 0; } |
Output
0x1365c20 A::show() A::show() 0x1365c20 0x1365c20 2 2 0 1 0x1365c20
Example 2:
C++
// C++ program to illustrate the use of make_shared #include <iostream> #include <memory> using namespace std; int main() { // Creating shared pointers using std::make_shared shared_ptr< int > shr_ptr1 = make_shared< int >(42); shared_ptr< int > shr_ptr2 = make_shared< int >(24); // Accessing the values using the dereference operator // (*) cout << "Value 1: " << *shr_ptr1 << endl; cout << "Value 2: " << *shr_ptr2 << endl; // Using the assignment operator (=) to share ownership shared_ptr< int > shr_ptr3 = shr_ptr1; // Checking if shared pointer 1 and shared pointer 3 // point to the same object if (shr_ptr1 == shr_ptr3) { cout << "shared pointer 1 and shared pointer 3 " "point to the same object." << endl; } // Swapping the contents of shared pointer 2 and shared // pointer 3 shr_ptr2.swap(shr_ptr3); // Checking the values after the swap cout << "Value 2 (after swap): " << *shr_ptr2 << endl; cout << "Value 3 (after swap): " << *shr_ptr3 << endl; // Using logical operators to check if shared pointers // are valid if (shr_ptr1 && shr_ptr2) { cout << "Both shared pointer 1 and shared pointer " "2 are valid." << endl; } // Resetting a shared pointer shr_ptr1.reset(); } |
Output
Value 1: 42 Value 2: 24 shared pointer 1 and shared pointer 3 point to the same object. Value 2 (after swap): 42 Value 3 (after swap): 24 Both shared pointer 1 and shared pointer 2 are valid.
Example 3: Implementing a Linked List Using std::shared_ptr
C++
#include <iostream> #include <memory> using namespace std; // Define a singly linked list node struct Node { int data; shared_ptr<Node> next; Node( int val) : data(val) , next(NULL) { } }; class LinkedList { public : LinkedList() : head(NULL) { } // Insert a new node at the end of the linked list void insert( int val) { shared_ptr<Node> newNode = make_shared<Node>(val); if (!head) { head = newNode; } else { shared_ptr<Node> current = head; while (current->next) { current = current->next; } current->next = newNode; } } // Delete a node with a given value from the linked list void del( int val) { if (!head) { return ; } if (head->data == val) { head = head->next; return ; } shared_ptr<Node> current = head; while (current->next && current->next->data != val) { current = current->next; } if (current->next && current->next->data == val) { current->next = current->next->next; } } // Traverse and print the linked list void Print() { shared_ptr<Node> current = head; while (current) { cout << current->data << " -> "; current = current->next; } cout << "NULL" << endl; } private : shared_ptr<Node> head; }; int main() { LinkedList linkedList; // Insert nodes into the linked list linkedList.insert(1); linkedList.insert(2); linkedList.insert(3); // Print the linked list cout << "Linked List: "; linkedList.Print(); // Delete a node and print the updated linked list linkedList.del(2); cout << "Linked List after deleting 2: "; linkedList.Print(); return 0; } |
Output
Linked List: 1 -> 2 -> 3 -> NULL Linked List after deleting 2: 1 -> 3 -> NULL
Contact Us