What is the make_unique in C++ & what is its benefit

In this article, we will discuss about the make_unique<>() in C++ and what are its advantages.

In the modern C++, memory management has been made significantly easier and safer through smart pointers. The std::make_unique<T>() is a utility function introduced in C++14. It lets the C++ runtime system handle memory allocation without the programmer needing to call new directly. This not only simplifies the code but also ensures that memory is managed safely, helping to prevent leaks and errors.

How does make_unique() Work?

The std::make_unique<T>() function is a part of the C++ Standard Library, and it encapsulates the process of creating a new object on the heap. Internally, it calls the new operator, but this is hidden from the programmer, providing a cleaner and less error-prone interface.

Here’s the general syntax for using std::make_unique:

auto ptrObj = std::make_unique<DATA_TYPE>(constructor_arguments);

You provide the Data Type of object you want to create, along with any arguments that the constructor of the object requires. std::make_unique then allocates memory for this object on the heap and returns a std::unique_ptr that owns this memory.

Initializing unique_ptr with make_unique()

When you call std::make_unique(), you can pass arguments to the constructor of the type being created. For instance, if you are working with a Tweet class that has a constructor accepting certain parameters, like this,

class Tweet
{
    private:
        std::string text; // The content of the tweet
        int viewCount;    // Number of times the tweet has been viewed
        int likeCount;    // Number of likes on the tweet
    public:
        // Constructor to initialize the tweet object with text, 
        // view count, and like count
        Tweet(const std::string &txt, int views, int likes)
            : text(txt), viewCount(views), likeCount(likes)
        {
            std::cout<< "*** Tweet::Constructor ***\n";
        }

        // Display function to print the details of the tweet
        void display() const
        {
            std::cout << "Tweet: " << text << "\n";
            std::cout << "Views: " << viewCount << "\n";
            std::cout << "Likes: " << likeCount << "\n";
        }
};

Now if you want to dynalically allocate memry on heap to store the Tweet object, then instead of calling new operator, we can create a unique_ptr object like this,

std::unique_ptr<Tweet> tweetPtr = std::make_unique<Tweet>("Good Morning", 3456, 13);

Here, tweetPtr is a unique pointer that will manage the Tweet object created with the specified text, viewCount, and likeCount.

With the std::unique_ptr returned by std::make_unique, you can use the object just like you would with a regular pointer. You can invoke methods, dereference it to modify the value, or even access the raw pointer if necessary (though that should be done with caution and typically only when interfacing with APIs that require raw pointers).

The Benefits of std::make_unique<> in C++

std::make_unique<> is a standard utility that creates a std::unique_ptr<>. Introduced in C++14, it is a safe way to create a unique_ptr and offers several advantages over directly using the new operator. Here are the key benefits of using std::make_unique<>:

  • Exception Safety

One of the most significant advantages of std::make_unique<> is that it provides stronger exception safety compared to using new directly. When you create a unique_ptr with new, if an exception occurs between the creation of the raw pointer and the construction of the unique_ptr, there is a risk of a memory leak. std::make_unique<> allocates memory and creates the object in a single step, thus avoiding this issue.

  • Code Clarity

Using std::make_unique<> makes the code more readable and expressive. It clearly indicates that you are transferring ownership to a unique_ptr.

  • Avoids Manual Memory Management

By using std::make_unique<>, you avoid manual memory management, thus reducing the chances of memory leaks and making the code cleaner and safer.

  • Perfect Forwarding

std::make_unique<> uses perfect forwarding, which means it can construct objects with complex constructors without any extra effort. It passes the given arguments to the constructor of the object it is creating, making it versatile for various use cases.

  • Reduces Code Repetition

When using new, the type of the object has to be repeated in the new expression. With std::make_unique<>, the type is only specified once in the angle brackets, which DRYs up the code (Don’t Repeat Yourself principle).

Summary

The std::make_unique<> function should be preferred over direct use of new when initializing unique_ptr. It enhances code safety, readability, and maintainability.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top