new je operátor programovacího jazyka C++ , který poskytuje dynamickou alokaci paměti na haldě . S výjimkou formuláře nazvaného " alokační formulář nový " se newpokusí alokovat dostatek paměti na haldě pro uložení nových dat a v případě úspěchu vrátí adresu umístění přidělené paměti. Pokud newvšak nemůže alokovat paměť na haldě, vyvolá výjimku typu std::bad_alloc. Tím odpadá nutnost explicitně kontrolovat výsledek výběru. Poté, co kompilátor narazí na klíčové slovo, newvygeneruje volání konstruktoru třídy [1] .
Syntaxe newvypadá takto:
p_var = nový název typu ;kde p_var je dříve deklarovaný ukazatel typu typename. typenamemůže znamenat jakýkoli základní datový typ nebo uživatelem definovaný objekt (včetně , enuma class) struct. Pokud typename se jedná o typ třídy nebo struktury, musí mít k dispozici výchozí konstruktor , který bude zavolán k vytvoření objektu.
Chcete-li inicializovat novou proměnnou vytvořenou pomocí new, použijte následující syntaxi:
p_var = nový typ ( inicializátor );kde initializer je počáteční hodnota přiřazená nové proměnné, a pokud type je typ třídy, pak initializer jsou argumenty konstruktoru.
newmůže také vytvořit pole :
p_var = newtype [ velikost ] ;V tomto případě sizeurčuje rozměr (délku) vytvořeného jednorozměrného pole. Adresa prvního prvku je vrácena a umístěna do p_var, takže
p_var [ n ]znamená hodnotu n-tého prvku (počítáno od pozice nula)
Paměť přidělená pomocí newmusí být uvolněna pomocí, aby se deletezabránilo úniku paměti . Pole alokovaná (vytvořená) pomocí new[], musí být uvolněna (zničena) pomocí delete[].
int * p_skalar = new int ( 5 ); int * p_array = new int [ 5 ];Inicializátory nelze zadat pro pole vytvořená pomocí new. Všechny prvky pole jsou inicializovány pomocí výchozího konstruktoru pro daný typ. Pokud typ nemá výchozí konstruktor, oblast přidělené paměti nebude inicializována.
Existuje speciální forma nového operátora s názvem Placement new. Tento operátor nealokuje paměť, ale bere jako svůj argument adresu do paměti již alokované nějakým způsobem (například na zásobníku nebo prostřednictvím malloc ()). Objekt je alokován (inicializován) voláním konstruktoru a objekt je vytvořen v paměti na zadané adrese. Tato metoda se často používá, když třída nemá výchozí konstruktor a potřebujete vytvořit pole objektů. Příklad volání vypadá takto:
#include <new> // Vyžadováno pro použití umístění new třída A { veřejnost : A ( int x ){} ~ A (){} }; const int n = 50 ; A * umístěníPaměť = static_cast < A *> ( operátor new [] ( n * sizeof ( A ))); for ( int i = 0 ; i < n ; i ++ ) { nové ( umístěníPaměť + i ) A ( rand ()); //zde paměť pro objekt není přidělena, ale je inicializována } //!!deinicializace paměti pro ( int i = 0 ; i < n ; i ++ ) { umístěníPaměť [ i ]. ~ A (); } operátor delete [] ( umístěníPaměť );Protože typ vytvářeného objektu (objektů) nebyl specifikován při alokaci paměti, kompilátor nezavolá destruktor pro každý objekt pole, takže to musí být provedeno ručně před uvolněním bloku paměti.
V kompilátorech , které dodržují standard ISO C++ , pokud není dostatek paměti k alokaci, pak výjimka typu std::bad_alloc. Provádění všech následujících kódů se zastaví, dokud není chyba zpracována v bloku try-catch nebo dokud se program neukončí abnormálně. Program nemusí kontrolovat hodnotu ukazatele; pokud nebyla vyvolána žádná výjimka, bylo přidělení úspěšné. Implementované operace jsou definovány v záhlaví <new>. Ve většině implementací C++ newmůže být operátor také přetížen , aby mohl definovat speciální chování.
Jakákoli dynamická paměť přidělená pomocí new, musí být uvolněna pomocí delete. Existují dvě možnosti: jedna pro pole, druhá pro jednotlivé objekty.
int * p_var = new int ; int * p_array = new int [ 50 ]; smazat p_var ; smazat [] p_array ;Norma nevyžaduje, aby kompilátor generoval diagnostickou zprávu při nesprávném použití delete; obecně nemůže vědět, kdy ukazatel ukazuje na jeden prvek a kdy ukazuje na pole prvků. Navíc použití nevhodného vydání je nedefinované chování .
Na rozdíl od funkce reallocv Cnew[] nemůže operátor přímo přerozdělit již přidělenou paměť. Chcete-li zvětšit nebo zmenšit velikost bloku paměti, musíte přidělit nový blok požadované velikosti, zkopírovat data ze staré paměti a starý blok odstranit. Standardní knihovna C++ poskytuje podporu pro dynamické pole , které lze inkrementovat nebo dekrementovat ve své šabloně třídy std::vector.