2010-09-09 13 views
72

En C++,¿Cuál es la diferencia entre una instancia de un objeto utilizando las nuevas vs. sin

Aparte de asignación dinámica de memoria, ¿hay una diferencia funcional entre las siguientes dos líneas de código:

Time t (12, 0, 0); //t is a Time object 

Time* t = new Time(12, 0, 0);//t is a pointer to a dynamically allocated Time object 

soy suponiendo, por supuesto, que se haya definido un Time (int, int, int) ctor. También me doy cuenta de que en el segundo caso, será necesario eliminarlo ya que fue asignado en el montón. ¿Hay alguna otra diferencia?

+7

Realmente no cuenta como una respuesta, pero aparte de las respuestas ya dadas, puede interesarte saber que puedes anular el operador nuevo/eliminar si deseas escribir tu propia gestión de memoria (para un mejor rendimiento). –

Respuesta

2

Creo que ya comprende todas las diferencias. Asumiendo que usted es consciente de la diferencia de sintaxis para acceder a un miembro de t a través de un puntero y una variable (bueno, el puntero también es una variable, pero supongo que comprende lo que quiero decir). Y suponiendo también que conoce la diferencia de llamada por valor y llama por referencia cuando pasa t a una función. Y creo que también entiendes lo que sucederá si asignas t a otra variable y realizas el cambio a través de esa otra variable. El resultado será diferente dependiendo de si t es puntero o no.

102

La línea:

Time t (12, 0, 0); 

... asigna una variable de tipo Time en ámbito local, generalmente en la pila, que será destruida cuando termina su alcance.

Por el contrario:

Time* t = new Time(12, 0, 0); 

... asigna un bloque de memoria ya sea llamando o ::operator new()Time::operator new(), y posteriormente se llama Time::Time() con this conjunto a una dirección dentro de ese bloque de memoria (y también obtiene como resultado de new), que luego se almacena en t. Como usted sabe, esto es generalmente hecho en el montón (de forma predeterminada) y requiere que delete más adelante en el programa, mientras que el puntero en t es generalmente almacenado en la pila.

+5

+1 por posible sobrecarga de 'operator new()' – Anthony

+5

+1: También diría que la asignación de la pila ** debe ** ser más rápida que la asignación de la pila. –

+0

"Una dirección dentro de ese bloque de memoria": ¿cualquier dirección en cualquier lugar dentro del bloque o en una ubicación específica como el comienzo? – Sev

5

En lo que se refiere al constructor, las dos formas son funcionalmente idénticas: simplemente provocarán que se llame al constructor sobre una instancia de objeto recientemente asignada. Ya parece tener una buena comprensión de las diferencias en términos de modos de asignación y duración de los objetos.

1

No existe una diferencia funcional para el objeto entre asignarlo en la pila y asignarlo al montón. Ambos invocarán el constructor del objeto.

Por cierto le recomiendo que utilice shared_ptr de impulso o scoped_ptr que también es funcionalmente equivalente al asignar en el montón (con la utilidad adicional de scoped_ptr que limitar a copiar punteros no copiable):

scoped_ptr<Time> t(new Time(12, 0, 0)); 
1

No .. No hay otra diferencia ..

1

No hay otra diferencia con lo que ya sabe.

Suponiendo que su código está utilizando el servicio del operador predeterminado nuevo.

22

Una diferencia más obvia es cuando se accede a las variables y métodos de t.

Time t (12, 0, 0); 
t.GetTime(); 

Time* t = new Time(12, 0, 0); 
t->GetTime(); 
-2
void foo (Time t) 
{ 
    t = Time(12, 0, 0); 
} 

void bar (Time* t) 
{ 
    t = new Time(12, 0, 0); 
} 


int main(int argc, char *argv[]) 
{ 
    Time t; 
    foo(t);//t is not (12,0,0),its value depends on your defined type Time's default constructor. 

    bar(&t);//t is (12,0,0) 
    return 0; 
} 
+0

Creo que su comentario "// t no es (12,0,0), su valor depende del tipo de constructor predeterminado del tipo definido." se aplica a la línea justo encima de ella, es decir, a la declaración del objeto t (Tiempo t;). – AamodG

1
  • Uso nueva: operador de llamada nueva función para obtener memoria dinámica, y luego llamar a la función Constuctor.
  • No usar nuevo: No llamará al operador nueva función, solo directamente para llamar a la función constuctor. La pila se usará directamente, sin uso para malloc.
Cuestiones relacionadas