2010-11-10 4 views
15

j'ai vu code comme ceci:pourquoi l'opérateur d'appel nouveau explicitement

void *NewElts = operator new(NewCapacityInBytes); 

Et appel correspondant explicitement operator delete est utilisé par conséquent plus tard.

Pourquoi faire au lieu de:

void *NewElts = new char[NewCapacityInBytes]; 

Pourquoi appel explicite à operator new et operator delete ??

+1

Avez-vous volontairement mis des crochets sur le second exemple? –

+0

Probablement prévu: 'new char [NewCapacityInBytes]' – MSalters

+0

@MSalters: vous avez raison, corrigé – zaharpopov

Répondre

24

Appeler explicitement operator new comme cela appelle l'opérateur global "brut" nouveau. Global operator new renvoie un bloc de mémoire brut sans appeler le constructeur de l'objet ou toute surcharge définie par l'utilisateur de new. Donc, fondamentalement, operator new global est similaire à malloc de C.

Alors:

// Allocates space for a T, and calls T's constructor, 
// or calls a user-defined overload of new. 
// 
T* v = new T; 

// Allocates space for N instances of T, and calls T's 
// constructor on each, or calls a user-defined overload 
// of new[] 
// 
T* v = new T[N]; 

// Simply returns a raw byte array of `sizeof(T)` bytes. 
// No constructor is invoked. 
// 
void* v = ::operator new(sizeof(T)); 
+2

quand est-ce utile? – zaharpopov

+6

@zaharpopov: Un exemple consisterait à implémenter un pool de mémoire dans lequel vous alloueriez un gros bloc une fois et les utilisateurs du pool appellent des fonctions qui créent des objets dans le bloc, au lieu d'utiliser 'new'. Selon le modèle d'allocation, cela peut fournir de meilleures performances que 'new' et' delete'. –

+0

Ooo. Intéressant. Je ne connaissais pas * ce * coin de C++. –

2

Si vous appelez l'opérateur new (bytesize), vous pouvez le supprimer à l'aide de supprimer, alors que si vous allouez par nouveau char [ bytesize], alors vous devez le faire correspondre en utilisant delete [], qui est une abomination à éviter autant que possible. C'est probablement la raison fondamentale pour l'utiliser.

+1

Comment est-ce une abomination? –

+3

Si vous allouez via 'operator new' global, vous pouvez le libérer en utilisant global' operator delete'. Mais global 'operator delete' n'appellera pas le destructeur. Donc, si vous construisez réellement un objet en utilisant new après avoir appelé global 'operator new', alors global 'operator delete' n'est pas suffisant pour détruire l'objet. Vous devez également appeler explicitement le destructeur avant de libérer la mémoire. Essentiellement, global 'operator new' et' operator delete' vous permettent de découpler allocation/désallocation de stockage et initialisation/destruction d'objets. –

+0

@Charles: Il n'a rien placé de nouveau, et cette mémoire n'a pas besoin d'être détruite. Comme une forme d'allocation de mémoire pure, alors l'opérateur new() est le pari le plus sûr car il n'a pas besoin de supprimer irritant [] ou inhabituel free() pour libérer. @Steve: delete [] est une abomination parce que c'est inutile. Ce n'est pas comme si, lorsque vous utilisez l'opérateur new et non new [], le tas n'a pas besoin de stocker la taille du bloc ou quelque chose comme ça. – Puppy

6

Si vous écrivez:

T *p = new T; 

qui alloue suffisamment de mémoire pour contenir un T, puis construit le T en elle. Si vous écrivez:

T *p = ::operator new(sizeof(T)); 

qui alloue suffisamment de mémoire pour contenir un T, mais ne pas construire le T. L'une des fois que vous pouvez voir c'est quand les gens utilisent également le placement nouvelle:

T *p = ::operator new(sizeof(T)); // allocate memory for a T 
new (p) T; // construct a T into the allocated memory 
p->~T(); // destroy the T again 
::operator delete(p); // deallocate the memory 
1

Utilisez-le lorsque vous voulez allouer un bloc de mémoire "brute" et que vous ne voulez rien construire dans cette mémoire. Il y a peu de différence pratique entre l'allocation d'un bloc de mémoire brute et la "construction" d'un tableau de caractères, mais l'utilisation d'un opérateur nouveau signale clairement votre intention à quiconque lisant le code qui est important.

Questions connexes