¿Diferencia entre 'nuevo operador' y 'nuevo operador'?

126

¿Cuál es la diferencia entre "operador nuevo" y "operador nuevo"?

Sandeep
fuente
3
Hola, ¿puedes aclarar la pregunta? Parece que hay un error tipográfico en alguna parte.
Dima Malenko
17
La pregunta está redactada correctamente, vea las respuestas a continuación. El método para asignar memoria dinámicamente es usar el newoperador. Este operador puede estar sobrecargado. Para distinguir entre el operador predeterminado y una versión sobrecargada, el predeterminado se llama "operador nuevo" y la versión sobrecargada se llama "operador nuevo".
Thomas Matthews
2
Como hacer eso. Soy nuevo e inconsciente.
Sandeep

Respuestas:

127

Por lo general, trato de expresar las cosas de manera diferente para diferenciar entre los dos un poco mejor, pero en cualquier caso es una buena pregunta.

Operador nuevo es una función que asigna memoria en bruto, al menos conceptualmente, no es muy diferente de malloc(). Aunque es bastante inusual a menos que esté escribiendo algo como su propio contenedor, puede llamar al operador nuevo directamente, como:

char *x = static_cast<char *>(operator new(100));

También es posible sobrecargar un operador nuevo globalmente o para una clase específica. IIRC, la firma es:

void *operator new(size_t);

Por supuesto, si sobrecarga un operador nuevo (ya sea global o para una clase), también querrá / necesitará sobrecargar también la eliminación del operador coincidente. Para lo que vale, también hay un operador nuevo [] que se usa para asignar memoria a las matrices, pero es casi seguro que ignore todo ese desastre por completo.

El nuevo operador es lo que normalmente usa para crear un objeto desde la tienda gratuita:

my_class *x = new my_class(0);

La diferencia entre los dos es que el operador new solo asigna memoria en bruto, nada más. El nuevo operador comienza utilizando el operador new para asignar memoria, pero luego invoca al constructor para el tipo correcto de objeto, por lo que el resultado es un objeto vivo real creado en esa memoria. Si ese objeto contiene cualquier otro objeto (ya sea incrustado o como clases base), esos constructores también se invocan.

Jerry Coffin
fuente
18
+1, en cuanto a una redacción diferente, el estándar usa una nueva expresión por todas partes, y solo una vez que usa un nuevo operador para referirse al lugar de la llamada. Tiendo a hacer lo mismo: operador nuevo para el asignador y nueva expresión para el uso.
David Rodríguez - dribeas
3
Una nueva expresión es toda la frase que comienza con nueva. Entonces, ¿cómo llamas a la parte "nueva"? Si es incorrecto llamar a ese nuevo operador, entonces no deberíamos llamar "sizeof" al operador de sizeof, y & la dirección del operador (cuando se comporta como tal).
Kaz
1
Siguiendo con el comentario de Kaz, tal vez la pregunta debería reformularse como: ¿Cuál es la diferencia entre el nuevo operador y el nuevo operador? :)
CS
2
"operador nuevo" vs "nueva palabra clave"
user997112
2
@antred: liberarías eso con algo como eso operator delete(x);.
Jerry Coffin
35

"operador nuevo"

class Foo
{
public:
        void* operator new( size_t );
}

"nuevo operador":

Foo* foo = new Foo();

En este ejemplo, las new Foo()llamadasFoo::operator new()

En otras palabras, "nuevo operador" llama " operator new()" al igual que el operador + llamaoperator +()

Austin Hyde
fuente
13
newno es un operador en C ++. sizeof, por ejemplo, es un operador, pero newy deleteno lo son. newy deleteson las palabras clave y las construcciones sintácticas que estas palabras clave se forman son llamados de nueva expresión y de eliminación expresión .
ANT
2
Uh, en todo caso, sizeofes la construcción sintáctica, y newy deleteson ambos, operadores de sobrecarga poder legal y válida. De todo lo que he visto, newy deleteson ambos operadores. Ver [cplusplus.com] [ cplusplus.com/doc/tutorial/classes2/]
Austin Hyde
77
Incorrecto. La terminología oficial de C ++ es la terminología definida por la especificación del lenguaje, no por algún sitio web. En la especificación del lenguaje no existe el término "operador nuevo", pero sí el término " operator newfunción". Una vez más, sizeofse hace referencia a explicilty como un "operador", mientras que newy deleteson nunca se refiere como operadores.
ANT
66
AndreyT: Incorrecto. El estándar C ++ llama 'nuevo' a un operador, ver 13.5 / 1.
3
@AndreyT: Pensé que, como ustedes, ese operador nuevo era el asignador y la nueva expresión los usos. Revisé y verifiqué que en §5.3.4 / 3 el estándar actual usa el término operador nuevo . Más adelante en §5.3.4 / 8 nombra las funciones del asignador como operador nuevo y operador nuevo []
David Rodríguez - dribeas
22

La siguiente es la cita del libro de C ++ más eficaz de Scott Meyers:

El nuevo operador llama a una función para realizar la asignación de memoria requerida, y puede reescribir o sobrecargar esa función para cambiar su comportamiento. El nombre de la función que el nuevo operador llama para asignar memoria es operador nuevo.

Naveen
fuente
77
El término es obviamente inventado por el autor del libro (o, tal vez, tomado prestado de alguna fuente obsoleta). En la nomenclatura formal de C ++ no existe el término "operador nuevo".
ANT
2
@AndreyT: Hice una búsqueda en el C ++ 11 para "nuevo operador" y lo encontré referenciado en cuatro lugares. Específicamente, dos referencias al "nuevo operador de colocación"
Mooing Duck
11

No hay diferencia entre "operador nuevo" y "operador nuevo". Ambos se refieren a lo mismo: la función sobrecargable / reemplazable operator newque generalmente realiza la asignación de memoria sin formato para objetos creados por nuevas expresiones .

Tenga en cuenta también que ninguno términos está presente en la especificación del lenguaje (que es la fuente definitoria de la terminología oficial).

Cuando usa newen su programa para crear un objeto, se llama nueva expresión . La nueva expresión consiste en palabras clave newy partes sintácticas adicionales definidas por la gramática. Ninguna parte de la sintaxis de esta expresión se denomina "operador".

La función de asignación de memoria sin formato operator newse conoce oficialmente como " operator newfunción". Tenga en cuenta que las palabras operatorynew en esta secuencia son solo dos palabras clave del lenguaje C ++ separadas. No forman un término en inglés "operador nuevo". En ninguna parte de la especificación del idioma encontrará referencias a "operador nuevo" como término en inglés. Cada vez, esto es solo una combinación de dos palabras clave independientes que producen una sintaxis de declaración para una función de asignación de memoria.

Nuevamente, en resumen: formalmente en C ++ no existen términos en inglés como "operador nuevo" o "nuevo operador". La primera secuencia está presente en la especificación del idioma como una mera combinación de palabras clave, no como un término en inglés. Este último no está presente en absoluto.

Hormiga
fuente
14
Pareces perdido en alguna pedante-masturbación mental. El estándar es vago en algunos puntos, y este es uno de ellos. Tiene tanto sentido "discutir el nuevo operador" como "discutir el operador más" o "discutir el operador +".
7

Cuando crea un nuevo objeto, la memoria se asigna utilizando el operador new y luego se invoca al constructor para inicializar la memoria. El nuevo operador realiza tanto la asignación como la inicialización, mientras que como operador nuevo solo realiza la asignación.

Chris Fulstow
fuente
6

La pregunta del OP no está redactada correctamente. ¿Es mejor cambiar de fase como 'Diferencia entre' operador nuevo 'y' nueva expresión '?' Nota 'operador nuevo' a menudo se refiere a 'operador nueva función' también.

Y hay muchas respuestas correctas, a continuación está la mía:

1> 'nueva expresión' llama 'operador nuevo' para asignar memoria sin procesar, luego llama al constructor

apple * p = new apple(); //new expression

2> 'operador nuevo' solo asigna memoria sin procesar, no hay mucha diferencia que malloc

void* mem = operator new(sizeof(apple)); //just like calling malloc()
apple* p2 = new(mem) apple(1); //call construct here using placement new.
Gob00st
fuente
2

El nuevo operador : C ++ admite la asignación dinámica de objetos utilizando el nuevo operador. El nuevo operador asigna memoria para objetos de un grupo llamado almacén gratuito. El nuevo operador llama al operador de función especial nuevo.

operador nuevo : si la solicitud es para cero bytes de almacenamiento, el operador nuevo devuelve un puntero a un objeto distinto (es decir, las llamadas repetidas al operador nuevo devuelven punteros diferentes). Si no hay memoria suficiente para la solicitud de asignación, el operador new devuelve NULL o lanza una excepción. El primer argumento para el operador new debe ser de tipo size_t (un tipo definido en STDDEF.H), y el tipo de retorno siempre es nulo *.

Aquí hay un enlace de MSDN para más detalles:

El operador nueva función

El nuevo operador

aJ.
fuente
1
Ligera aclaración: el nuevo operador de no colocación siempre debe arrojar el fallo de asignación (según el estándar); y los formularios de ubicación, como ::new(std::nothrow), pueden hacer cualquiera de ellos (ese ejemplo específico devuelve un puntero nulo).
1
  1. new es un operador además de una palabra clave.

    ver [1] en 2.13 && en 2.12.

  2. nuevo hace dos cosas: T * t = nuevo T (arg);

    1) asignar memoria para el objeto: void * ptr = operador nuevo (sizeof (T));

    // operator new es una función (al igual que malloc en c), no un operador (ver [1] en 3.7.4). Pero el ítem 7 [2] dijo que también es un operador. En mi opinión, la diferencia entre operador y función es pequeña, y puede verla cuando recuerda que el operador de sobrecarga está implementado por funciones.

    // podemos sobrecargar este operador / función (operador nuevo) haciendo lo que queremos justo aquí.

    2) inicialice el objeto en la memoria asignada: llame a T :: T (arg) en ptr

    // solo el compilador puede hacer esto. Ni yo ni tú podemos.

    // también el compilador invocará los constructores de objetos miembros y el constructor de la clase base si T los tiene. Y esta invocación es recursiva. Solo el compilador puede hacer eso.

  3. Entonces, el operador nuevo hace parte de las misiones de nuevo, y solo en esta parte podemos hacer algo.

    [1]: ISO / IEC, N3690. http://ww.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf

    [2]: Meyers, Scott. Efectivo C ++, 3er.

njuhgn
fuente