std::make_unique în C++

Creează un obiect pe heap și returnează un std::unique_ptr care îl deține.

Sintaxă
template<class T, class... Args>
std::unique_ptr<T> make_unique(Args&&... argumente);
template<class T>
std::unique_ptr<T[]> make_unique(std::size_t n);

Ce face std::make_unique

std::make_unique<T>(argumente) face într-un singur pas new T(argumente) și pune rezultatul într-un std::unique_ptr<T>. Argumentele sunt trimise direct constructorului lui T.

Este forma recomandată: nu scrii new deloc, tipul apare o singură dată (poți folosi auto) și nu există niciun moment în care memoria să rămână fără proprietar.

Cu std::make_unique<T[]>(n) creezi un tablou de n elemente inițializate cu valoarea implicită (0 pentru numere).

Parametri

Parametru Descriere
argumente Valorile trimise constructorului lui T.
n Pentru forma cu tablou: numărul de elemente.

Ce returnează

Un std::unique_ptr<T> (sau std::unique_ptr<T[]>) care deține obiectul nou.

Exemple

Exemplul 1: Un obiect cu constructor

#include <memory>
#include <print>
#include <string>

struct Produs {
    std::string nume;
    double pret;
    Produs(std::string n, double p) : nume(std::move(n)), pret(p) {}
};

int main() {
    auto p = std::make_unique<Produs>("Cafea", 24.5);
    std::println("{} costă {} lei", p->nume, p->pret);
}

Rezultat

Cafea costă 24.5 lei

Exemplul 2: Un tablou alocat dinamic

Elementele sunt inițializate cu 0. Accesul se face cu [], iar la final tabloul este șters cu delete[], automat.

#include <memory>
#include <print>

int main() {
    const int n = 5;
    auto patrate = std::make_unique<int[]>(n);
    for (int i = 0; i < n; ++i) {
        patrate[i] = i * i;
    }
    for (int i = 0; i < n; ++i) {
        std::print("{} ", patrate[i]);
    }
    std::println();
}

Rezultat

0 1 4 9 16

Greșeli frecvente

  • Scrii std::unique_ptr<T> p(new T) peste tot. Funcționează, dar make_unique este mai scurt și nu lasă memoria fără proprietar dacă o excepție apare între alocare și construirea pointerului.
  • Folosești make_unique<int>(5) crezând că face un tablou de 5 elemente. Face un singur int cu valoarea 5; pentru tablou scrie make_unique<int[]>(5).

Comenzi înrudite

  • std::unique_ptr: Pointer inteligent care deține singur un obiect și îl șterge automat când iese din domeniu.
  • std::make_shared: Creează un obiect și un std::shared_ptr care îl deține, cu o singură alocare de memorie.
  • new: Creează un obiect în memoria dinamică (heap) și returnează un pointer la el; obiectul trăiește până este distrus explicit cu delete.