Si ‘Prueba’ es una clase ordinaria, ¿hay alguna diferencia entre:

Test* test = new Test;

y

Test* test = new Test();
Esto se relaciona con el (pero no idéntico) stackoverflow.com/questions/1613341/…
Solo uso nueva Prueba() para asegurarse de que es inicializada en cero

OriginalEl autor David Read | 2009-03-06

5 Comentarios

  1. 879

    Vamos a llegar pedante, porque hay diferencias de las que realmente puede afectar a su código de conducta. Mucho de lo siguiente es tomado de los comentarios realizados a una La «vieja» Nueva Cosa» artículo.

    A veces la memoria devuelta por el nuevo operador será inicializado, y a veces no, dependiendo de si el tipo que te newing es un POD (plain old datos), o si es una clase que contiene POD miembros y es el uso de un compilador genera constructor predeterminado.

    • En C++1998 hay 2 tipos de inicialización: el cero y el valor predeterminado
    • En C++2003 un 3er tipo de inicialización, el valor de inicialización.

    Asumir:

    struct A { int m; }; //POD
    struct B { ~B(); int m; }; //non-POD, compiler generated default ctor
    struct C { C() : m() {}; ~C(); int m; }; //non-POD, default-initialising m

    En un compilador de C++98, las siguientes circunstancias:

    • new A – indeterminado valor
    • new A() – cero inicializar

    • new B – defecto de construcción (B::m es sin inicializar)

    • new B() – defecto de construcción (B::m es sin inicializar)

    • new C – defecto de construcción (C::m es inicializada en cero)

    • new C() – defecto de construcción (C::m es inicializada en cero)

    En C++03 adecúa compilador, las cosas deberían funcionar así:

    • new A – indeterminado valor
    • new A() – valor-inicializar Una, que es la inicialización de cero, ya que es un POD.

    • new B – default-inicializa (hojas B::m sin inicializar)

    • new B() – valor-inicializa B que cero inicializa todos los campos, desde su defecto cto r es el compilador genera como contraposición a la definida por el usuario.

    • new C – default-inicializa C, que llama a la predeterminada cto r.

    • new C() – valor-inicializa C, que llama a la predeterminada cto r.

    Así en todas las versiones de C++ hay una diferencia entre new A y new A() porque es una VAINA.

    Y hay una diferencia en el comportamiento entre C++98 y C++03 para el caso new B().

    Este es uno de los polvorientos rincones de C++ que puede volverte loco. Cuando la construcción de un objeto, a veces quiere/necesita el paréntesis, a veces usted no puede tener, y a veces no importa.

    new A() se predeterminado-inicializar el objeto en C++98, como hace con new B(), new B, new C() y new C, pero no con new A. Es decir, inicialización predeterminada siempre está hecho en C++98 cuando: 1) La clase es un no-POD y el inicializador falta, o 2) El inicializador es (). -defecto de inicialización en cero inicializa el objeto si es una VAINA, pero llama al constructor por defecto para los no-PODs.
    Alguien puede añadir lo que es el caso de C++11 ahora?
    Con C++11 usted puede hacer esto en la pila demasiado; B obj{}; hará que el objeto de valor inicializado (0s) frente a B obj; que será por defecto-inicializa (basura).
    Bueno, yo diría que depende. No todas las clases son escritos por el exterior del consumo, donde el cliente es algo de Joe programador que no sabe; algunas clases están escritos para una biblioteca de consumo interno, en esos casos supongo que va con la VAINA es mejor, pero en los casos donde es absolutamente necesario siempre inicializar vars en un estado en particular (y perf. no es un problema), a continuación, cto r parece ser mejor.
    AFAIK haciendo = default; que son explícitamente proporciona un constructor (incluso tho es un compilador genera uno, por lo que son en el caso B). Si usted no proporciona un constructor, el compilador podría implícitamente generar de todos modos (que permanecen en el caso a). El resultado es el mismo: Un nuevo/B> inicialización predeterminada, nueva A/B() -> valor de inicialización a cero. Sin embargo, en C++11 no debe considerar las Vainas pero agregados…

    OriginalEl autor Michael Burr

  2. 52

    new Thing(); es explícito que desea un constructor llamado mientras que new Thing; se supone que no me importa si el constructor no es llamado.

    Si se utiliza en una estructura de clase o con un usuario definido por el constructor, no hay ninguna diferencia. Si se llama a un trivial struct/clase (por ejemplo,struct Thing { int i; };), a continuación, new Thing; es como malloc(sizeof(Thing)); mientras que new Thing(); es como calloc(sizeof(Thing)); – se pone a cero inicializa.

    El problema yace en el medio:

    struct Thingy {
      ~Thingy(); //No-longer a trivial class
      virtual WaxOn();
      int i;
    };

    El comportamiento de new Thingy; vs new Thingy(); en este caso se ha cambiado entre C++98 y C++2003. Ver a Michael Burr explicación de cómo y por qué.

    OriginalEl autor kfsone

  3. 19

    No, son la misma. Pero hay una diferencia entre:

    Test t;      //create a Test called t

    y

    Test t();   //declare a function called t which returns a Test

    Esto es debido a que el básico de C++ (y C) de la regla: Si algo puede ser, posiblemente, una declaración, entonces es una declaración.

    Edición: Volver a la inicialización de los problemas con respecto a la VAINA y no POD de datos, aunque estoy de acuerdo con todo lo que ha dicho, me gustaría señalar que estos problemas sólo se aplican si la cosa está nuevo d o de lo contrario construido no tiene un usuario definido por el constructor. Si hay un constructor que va a ser utilizado. Para el 99,99% de sensatez diseñado clases habrá un constructor, y así los problemas pueden ser ignorados.

    Tenga en cuenta que este es un punto particularmente importante debido a que la línea «de la Prueba t(5);» es equivalente a «Prueba de t = Prueba(5);» … pero «la Prueba de t();» es muy diferente de la «Prueba de t = Prueba();». +1
    -1, no estoy de acuerdo con su declaración de que los problemas pueden ser ignorados. Usted no tiene que saber las reglas precisamente, pero usted debe ser consciente de ellos en caso de que usted tenga de nuevo una clase sin un usuario definido por el constructor predeterminado (a continuación, usted debe escribir el constructor o buscar las reglas).
    -1 para un conocido respuesta incorrecta. Su Edición ignora la presencia de código escrito por el ex programadores de C que no entiendo/constructores de uso.
    ¿Qué acerca de las clases como struct punto { float v[3]; };? Por cosas como esa, un constructor sería una mala idea, ya que evitaría que todos los lindos propiedades que vienen con ser POD y agregado. Así que «los problemas pueden ser ignorados» está mal, de la omi.
    Pero ellos no son el mismo. Esta respuesta es totalmente malo. Debería ser corregido o eliminado, debido a que parece haber causado un poco de confusión, a juzgar por el alto número de votos.

    OriginalEl autor

  4. 16

    En general, tenemos por defecto-inicialización en el primer caso y el valor de inicialización en el segundo caso.

    Por ejemplo:
    en el caso de los de tipo int (tipo de POD):

    • int* test = new int – tenemos cualquier inicialización y el valor de *prueba puede ser cualquiera.

    • int* test = new int() – *prueba tendrá el valor 0.

    siguiente comportamiento dependiendo de su tipo de Prueba.
    Hemos defferent casos: Prueba de defult constructor de la Prueba, han generado un constructor por defecto, Prueba de contener POD miembro, no POD miembro…

    OriginalEl autor bayda

  5. 10

    Suponiendo que la Prueba es una clase con un constructor, no hay ninguna diferencia. La última forma hace que sea un poco más clara que la Prueba del constructor se ejecuta, pero de eso se trata.

    OriginalEl autor Evan Shaw

Dejar respuesta

Please enter your comment!
Please enter your name here