2009-09-03 31 views
13

Puede alguien decirme cuál es la diferencia entre:C++ para la clase

Display *disp = new Display(); 

y

Display *disp; 
disp = new Display(); 

y

Display* disp = new Display(); 

y

Display* disp(new Display()); 
+0

Pero por qué "nueva pantalla" en el primer caso y "nueva GzDisplay" en el segundo? –

+0

también hay alguna diferencia en "Display * disp = new Display();" –

+0

No, su pregunta no es "maloliente". Sigue haciendo tus preguntas y seguiremos respondiendo. :) – jdelator

Respuesta

14

El primer caso:

Display *disp = new Display(); 

hace tres cosas:

  1. Se crea una nueva variable disp, con el tipo Display*, es decir, un puntero a un objeto de tipo Display, y luego
  2. Se asigna un nuevo objeto Display en el montón, y
  3. Se establece el disp var es probable que apunte al nuevo objeto Display.

En el segundo caso:

Display *disp; disp = new GzDisplay(); 

se crea una variable disp con el tipo Display*, y luego crear un objeto de un tipo diferente, GzDisplay, en el montón, y asignar su puntero a la variable disp.

Esto solo funcionará si GzDisplay es una subclase de Pantalla. En este caso, parece un ejemplo de polymorphism.

Además, para hacer frente a su comentario, no hay diferencia entre las declaraciones:

Display* disp; 

y

Display *disp; 

Sin embargo, debido a la forma C reglas de trabajo tipo, hay una diferencia entre :

Display *disp1; 
Display* disp2; 

y

Display *disp1, disp2; 

Debido a que en este último caso disp1 es un puntero a un objeto Display, probablemente asignada en el montón, mientras disp2 es un objeto real, probablemente asignado en la pila. Es decir, aunque el puntero es posiblemente parte del tipo, el analizador lo asociará con la variable.

+2

Ha cambiado la pregunta. GzDisplay ya no existe. –

+0

@ Daniel: Creo que estás confundido; SO solo muestra el autor de la edición más reciente; debe hacer clic en "hace 17 minutos" (o en cualquier momento que se muestre) para ver todas las revisiones y quién las hizo. Cuando hagas eso, descubrirás que el póster original cambió la pregunta. Comenta en meta.stackoverflow.com si sientes que la interfaz de usuario es confusa. – derobert

+0

@derobert: Mis disculpas. He eliminado mis comentarios. –

0

Uno crea un objeto de tipo Display y uno del tipo GzDisplay, ¿es esto a propósito o es un error tipográfico?

Si se trata de un error tipográfico, entonces no hay diferencia en cuanto al código generado, pero se prefiere el primer método, ya que no hay un momento en el que la variable disp esté dentro del alcance y no inicializada.

0

1) Instancia de GzDisplay se crea en la 2da variante, mientras que en la 1ra variante, la instancia creada es de Tipo de visualización (supongo que GzDisplay es la subclase de Pantalla, ¿verdad?); 2) Además de que el primero es más corto, en el segundo disp tiene un valor indefinido hasta que se le asigna un nuevo GzDisplay(). La segunda variante te da la oportunidad de olvidarlo accidentalmente e insertar algún código que use disp antes de inicializarlo.

1
Display *disp = new Display(); 

Esta línea de código crea una variable de tipo Mostrar * y la inicializa con la dirección de un objeto recién creado.

Display *disp;  // (1) 
disp = new Display(); // (2) 

La primera línea del código simplemente declara una variable de tipo Mostrar *. Según la configuración del compilador, el puntero puede o no inicializarse. Básicamente, debe tratarse como un puntero no válido, que no necesariamente apunta a NULL.

La segunda línea asigna la dirección de un objeto recién creado al puntero.

El resultado de ambos fragmentos de código será el mismo.

Con las optimizaciones habilitadas, cualquier compilador debe generar el mismo ensamblaje para ambas. Con optimizaciones deshabilitadas y con generación de código de depuración (ambos fragmentos pueden generar código totalmente diferente), en el segundo caso, el puntero se inicializaría primero con un valor utilizado por el compilador para punteros no inicializados (algo como 0xDEADBEEF o 0xEFEFEFEF) y fácilmente reconocible patrón). En el primer fragmento, el puntero siempre debe inicializarse en la dirección del objeto, independientemente de la configuración. Tenga en cuenta que esto depende del compilador: algunos compiladores pueden hacer lo que digo, algunos pueden hacer algo completamente diferente.

1

Ha encontrado cuatro formas de escribir lo mismo. Los ejemplos 1 (Display *disp…) y 3 (Display* disp…) son idénticos; el espaciado alrededor de * no importa. Sin embargo, el estilo de 1 a menudo se prefiere, debido a que:

Display* disp1, disp2; 

en realidad significa:

Display *disp1, disp2; 

es decir, DISP2 no es un puntero.

El ejemplo dos (división en dos líneas) tiene el mismo efecto, y probablemente se compilará con el mismo código. El cuarto ejemplo, usando la sintaxis del inicializador, hace lo mismo también.

Tenga en cuenta que si se tratara de clases, no de punteros, podría haber una diferencia en el comportamiento y la velocidad.

+0

@Daniel: No hice tal cosa. http://stackoverflow.com/revisions/1371608/list, revisión 4, muestra que OP cambia su propia pregunta. Acabo de arreglar su formateo para él. – derobert

+0

@derobert: retraído, mis disculpas. Como todavía no tengo suficientes representantes para editar las preguntas de los demás, no sabía cómo buscar en las revisiones anteriores de una pregunta. También eliminé mi voto negativo. –

5
// implicit form 
// 1) creates Display instance on the heap (allocates memory and call constructor with no arguments) 
// 2) creates disp variable on the stack initialized with pointer to Display's instance 
Display *disp = new Display(); 

// explicit form 
// 1) creates Display instance on the heap (allocates memory and call constructor with no arguments) 
// 2) creates disp variable on the stack initialized with pointer to Display's instance 
Display* disp(new Display()); 

// 1) creates uninitialized disp variable on the stack 
// 2) creates Display instance on the heap (allocates memory and call constructor with no arguments) 
// 3) assigns disp with pointer to Display's instance 
Display *disp; 
disp = new Display(); 

La diferencia entre las formas de inicialización explícitas e implícitas se verá solo para los tipos complejos con constructores. Para el tipo de puntero (Pantalla *) no hay diferencia.

Para ver la diferencia entre las formas explícitas e implícitas retirar el siguiente ejemplo:

#include <iostream> 

class sss 
{ 
public: 
    explicit sss(int) { std::cout << "int" << std::endl; }; 
    sss(double) { std::cout << "double" << std::endl; }; 
    // Do not write such classes. It is here only for teaching purposes. 
}; 

int main() 
{ 
sss ddd(7); // prints int 
sss xxx = 7; // prints double, because constructor with int is not accessible in implicit form 

return 0; 
} 
Cuestiones relacionadas