2010-11-10 13 views
15

vi código como este:qué operador de llamada nueva forma explícita

void *NewElts = operator new(NewCapacityInBytes); 

Y de llamada coincidente explícitamente operator delete se utiliza consiguiente más tarde.

Por qué hacer esto en lugar de:

void *NewElts = new char[NewCapacityInBytes]; 

Por qué llamada explícita a operator new y operator delete ??

+1

¿Pusiste corchetes en el segundo ejemplo a propósito? –

+0

Probablemente previsto: 'new char [NewCapacityInBytes]' – MSalters

+0

@MSalters: tiene razón, solucionado – zaharpopov

Respuesta

24

Llamar explícitamente al operator new así llama al operador global "en bruto" nuevo. Global operator new devuelve un bloque de memoria sin formato sin llamar al constructor del objeto ni a las sobrecargas definidas por el usuario de new. Así que, básicamente, global operator new es similar a la de C. malloc

Así:

// 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

¿Cuándo es útil? – zaharpopov

+6

@zaharpopov: Un ejemplo sería la implementación de un grupo de memoria donde se asigna una gran porción y los usuarios del grupo llamarían funciones que crean objetos dentro del fragmento, en lugar de usar 'new'. Según el patrón de asignación, esto puede proporcionar un mejor rendimiento que 'new' y' delete'. –

+0

Ooo. Interesante. No sabía sobre * esta * esquina de C++. –

2

Si llama operador de nuevo (ByteSize), a continuación, se puede eliminar el uso de borrar, mientras que si se puede asignar a través de nueva char [ bytesize], entonces tiene que coincidir con delete [], que es una abominación que debe evitarse siempre que sea posible. Esta es probablemente la razón principal para usarlo.

+1

¿Cómo es una abominación? –

+3

Si asigna vía global 'operator new' puede desasignarlo utilizando global' operator delete'. Pero el 'operador global delete' no llamará al destructor. Por lo tanto, si realmente construyes un objeto utilizando la colocación new después de llamar a global 'operator new', entonces' operator delete' global no es suficiente para destruir el objeto. También debe invocar el destructor explícitamente antes de desasignar la memoria. Esencialmente, tanto 'operator new' como' operator deleted 'global le permiten desacoplar la asignación/desasignación de almacenamiento y la inicialización/destrucción de objetos. –

+0

@Charles: No hizo nada nuevo, y esa memoria no necesita ser destruida. Como una forma de asignación pura de memoria, entonces el operador new() es la apuesta más segura porque no necesita irritantes delete [] o inusual free() para desasignar. @Steve: delete [] es una abominación porque no es necesario. No es así, cuando usas operador nuevo y no nuevo [], que el montón mágicamente no necesita almacenar el tamaño del bloque ni nada de eso. – Puppy

6

si escribe:

T *p = new T; 

que asigna suficiente memoria para mantener una T, entonces construye el T en él. Si se escribe:

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

que asigna suficiente memoria para mantener una T, pero no construya la T. Una de las veces que se pueden ver esto es cuando las personas están utilizando también la colocación de nuevo:

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

Úselo cuando desee asignar un bloque de memoria "en bruto" y no desee nada construido en esa memoria.

Hay poca diferencia práctica entre asignar un bloque de memoria sin procesar y "construir" una matriz de caracteres, pero usar el operador nuevo indica claramente su intención a cualquiera que lea el código que sea importante.

Cuestiones relacionadas