std::unique_ptr is a smart pointer class similar to SmartPointer that we have implemented. It comes with move semantics and does not support copy constructor and copy assignment.

We can simply use this class to create smart pointers as shown below:

#include <iostream>
#include <memory>
 
class Person
{
 
public:
    Person()
    {
        std::cout << "Creating person" << '\n';
    }
 
    ~Person()
    {
        std::cout << "Destroying person" << '\n';
    }
 
    void sayHello() const
    {
        std::cout << "Hi" << '\n';
    }
 
    friend std::ostream &operator<<(std::ostream &out, const Person &p)
    {
        return out << "Person()" << "\n";
    }
};
 
int main(int argc, char const *argv[])
{
    std::unique_ptr<Person> p_ptr{new Person()};
 
    std::cout << *p_ptr << '\n';
    return 0;
}

We require to include <memory> header to use std::unique_ptr.

std::make_unique() C++14

C++14 provides std::make_unique() which is another (and preferred) way to create std::unique_ptr. It directly takes the arguments to be passed to the resource, creates the resource and std::unique_ptr inside. This way, it solves a problem the directly creating std::unique_ptr.

For example:

auto p_ptr{std::make_unique<Person>()};

Currently, Person does not accept any arguments, but for the sake of argument, if it does, we can pass it like:

auto p_ptr{std::make_unique<Person>("Name", 12)};

To understand the problem it solves, consider the following code snippet:

void print(std::unique_ptr<Person> p, int value)
{
    std::cout << *p << '\n';
}
 
int raise_assert_exception()
{
    assert(1 != 1);
    return 1;
}
 
int main(int argc, char const *argv[])
{
    print(std::unique_ptr<Person>{new Person()}, raise_assert_exception());
    return 0;
}

If compiler implementation decides to evaluate this statement, first creating the Person and then calling the function raise_assert_exception(), and then creating std::unique_ptr. However, raise_assert_exception() raises the exception and resource is created but not destroyed because the smart pointer is not even created.

So, using std::make_unique solves this problem by creating the resource inside.

Resources

  1. https://www.learncpp.com/cpp-tutorial/stdunique_ptr/