Open In App

How to Create a Smart Pointer in C++?

smart pointer in C++ simulates a pointer while also providing automatic garbage collection as it deallocates or frees associated memory when it goes out of scope, which helps prevent memory leaks and dangling pointers. In this article, we will learn how to create a smart pointer in C++.

Creating a Smart Pointer in C++

The C++ libraries provide the following types of smart pointers:

1. unique_ptr

std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope.

Syntax to Create unique_ptr

unique_ptr<A> ptr1 (ptrToMemory)

or you can use the std::make_unique() function that can directly create a unique pointer to the memory of a given type.

unique_ptr<A> ptr = make_unique(type);

Here,

Example:

The following program illustrates how we can create unique_ptr in C++.

// C++ Program to illustrate how we can create unique_ptr
#include <iostream>
#include <memory>
using namespace std;

class Car {
private:
    string brand;
    int year;

public:
    Car(const string& brand, int year)
        : brand(brand)
        , year(year)
    {
    }

    void display() const
    {
        cout << "Brand: " << brand << ", Year: " << year
             << endl;
    }
};

int main()
{
    // Creating a unique_ptr to a Car object
    unique_ptr<Car> carPtr(new Car("Toyota", 2022));
    carPtr->display(); // Displaying the information of the
                       // Car

    // Creating another unique_ptr and transferring
    // ownership
    unique_ptr<Car> newCarPtr;
    newCarPtr = move(carPtr);

    // Displaying the information of the new Car
    if (newCarPtr) {
        newCarPtr->display();
    }
    else {
        cout << "No Car object available." << endl;
    }

    // Trying to access the old Car object (P1), which has
    // been moved from
    if (carPtr) {
        carPtr->display();
    }
    else {
        cout << "No Car object available (P1)." << endl;
    }

    return 0;
}

Output
Brand: Toyota, Year: 2022
Brand: Toyota, Year: 2022
No Car object available (P1).

2. Shared_ptr

std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer hence, several shared_ptr objects may own the same object, and the object is destroyed when the last shared_ptr is destroyed.

Syntax to Create std::shared_ptr

shared_ptr <T> ptr_name(ptrToMemory);

or you can use the std::make_shared() function that can directly create a unique pointer to the memory of a given type.

shared_ptr<A> ptr = make_shared(type);

Here,

Example:

The following program illustrates how we can create shared_ptr in C++.

// C++ Program illustrates how we can create shared_ptr
#include <iostream>
#include <memory>
using namespace std;

class Animal {
public:
    virtual void speak() const = 0;
};

class Dog : public Animal {
public:
    void speak() const override
    {
        cout << "Woof! Woof!" << endl;
    }
};

int main()
{
    // Creating a shared_ptr to a Dog object
    shared_ptr<Dog> dogPtr(new Dog);

    // Creating a weak_ptr from the shared_ptr
    weak_ptr<Dog> weakDogPtr(dogPtr);

    // Using the weak_ptr to access the Dog object
    if (auto shared = weakDogPtr.lock()) {
        shared->speak();
    }
    else {
        cout << "The object is no longer available."
             << endl;
    }

    // Outputting the use count of the shared_ptr
    cout << "Use count: " << dogPtr.use_count() << endl;

    return 0;
}

Output
Woof! Woof!
Use count: 1

3. Weak_ptr

std::weak_ptr is a smart pointer that holds a non-owning (“weak”) reference to an object that is managed by std::shared_ptr so it must be converted to std::shared_ptr in order to access the referenced object.

Syntax to Create weak_ptr

weak_ptr<type> ptr_name;

here,

Example:

The following program illustrates how we can create weak_ptr in C++.

// C++ Program to illustrate how we can create weak_ptr
#include <iostream>
#include <memory>
using namespace std;

class Animal {
public:
    virtual void sound() const = 0;
};

class Cat : public Animal {
public:
    void sound() const override { cout << "Meow!" << endl; }
};

int main()
{
    // Creating a shared_ptr to a Cat object
    shared_ptr<Cat> catPtr(new Cat);

    // Creating a weak_ptr from the shared_ptr
    weak_ptr<Cat> weakCatPtr(catPtr);

    // Using the weak_ptr to access the Cat object
    if (auto shared = weakCatPtr.lock()) {
        shared->sound();
    }
    else {
        cout << "The object is no longer available."
             << endl;
    }

    // Outputting the use count of the shared_ptr
    cout << "Use count: " << catPtr.use_count() << endl;

    return 0;
}

Output
Meow!
Use count: 1
Article Tags :