Open In App

shared_ptr in C++

Last Updated : 20 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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++.

shared_ptr-in-CPP

Shared Pointer 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


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads