std::make_unique


Function: std::make_unique

std::make_unique is a utility function template introduced in C++14 that creates a std::unique_ptr to an object of a specified type. It provides a safer and more convenient way to create unique pointers compared to directly using the new operator.

Key Characteristics

Example 1: Basic Usage

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass(int value) : value_(value) {
        std::cout << "MyClass constructed with value: " << value_ << std::endl;
    }
    ~MyClass() {
        std::cout << "MyClass destructed" << std::endl;
    }
    int getValue() const { return value_; }
private:
    int value_;
};

int main() {
    auto ptr = std::make_unique<MyClass>(42);
    std::cout << "Value: " << ptr->getValue() << std::endl;
    return 0;
}

Explanation:

Example 2: Exception Safety

#include <iostream>
#include <memory>
#include <stdexcept>

class Risky {
public:
    Risky(bool throwException) {
        if (throwException) {
            throw std::runtime_error("Construction failed");
        }
        std::cout << "Risky object constructed" << std::endl;
    }
    ~Risky() {
        std::cout << "Risky object destructed" << std::endl;
    }
};

void unsafeFunction(std::unique_ptr<Risky> ptr, bool throwException) {
    if (throwException) {
        throw std::runtime_error("Function exception");
    }
}

int main() {
    try {
        unsafeFunction(std::make_unique<Risky>(false), true);
    } catch (const std::exception& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
    }
    return 0;
}

Explanation:

Example 3: Creating Arrays (C++20)

#include <iostream>
#include <memory>

int main() {
    auto arr = std::make_unique<int[]>(5);
    for (int i = 0; i < 5; ++i) {
        arr[i] = i * 10;
    }

    for (int i = 0; i < 5; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

Explanation:

Example 4: Returning std::unique_ptr from a Function

#include <iostream>
#include <memory>
#include <string>

class Resource {
public:
    Resource(const std::string& s) : data_(s) {
        std::cout << "Resource acquired: " << data_ << std::endl;
    }
    ~Resource() {
        std::cout << "Resource released: " << data_ << std::endl;
    }
    void use() const {
        std::cout << "Using resource: " << data_ << std::endl;
    }
private:
    std::string data_;
};

std::unique_ptr<Resource> createResource(const std::string& data) {
    return std::make_unique<Resource>(data);
}

int main() {
    auto resource = createResource("Important Data");
    resource->use();
    return 0;
}

Explanation:

Additional Considerations

  1. Performance: std::make_unique typically has the same performance as directly using new with std::unique_ptr.

  2. Custom Deleters: std::make_unique doesn't support custom deleters. Use the std::unique_ptr constructor directly if you need a custom deleter.

  3. Type Deduction: When used with auto, std::make_unique allows for easier type deduction.

  4. Preventing Double Allocation: Using std::make_unique can prevent issues where new might be called multiple times in a single expression.

  5. C++17 and Later: While still useful, the exception safety benefits of std::make_unique are less critical in C++17 and later due to guaranteed copy elision.

Summary

std::make_unique is a valuable tool in modern C++ for creating std::unique_ptr objects. It offers improved exception safety, cleaner syntax, and helps prevent common errors associated with manual memory management. While it doesn't support custom deleters, it's the preferred method for creating unique pointers in most scenarios. Understanding and using std::make_unique is crucial for writing safe and efficient C++ code, especially when dealing with dynamic memory allocation and ownership semantics.

Citations:

[1] https://stackoverflow.com/questions/53870522/why-use-stdmake-unique-in-c17 [2] https://cplusplus.com/forum/beginner/272967/ [3] https://www.lewuathe.com/2020-10-29-return-std-make_unique-from-function/ [4] https://cplusplus.com/forum/general/284342/ [5] https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique

Previous Page | Course Schedule | Course Content