Tengo este struct:

struct Snapshot
{
    double x; 
    int y;
};

Quiero x y y a ser 0. Van a ser 0 por defecto o tengo que hacer:

Snapshot s = {0,0};

¿Cuáles son las otras formas de puesta a cero de la estructura?

InformationsquelleAutor | 2009-07-01

8 Comentarios

  1. 242

    Que no son nulos si no inicializar la estructura.

    Snapshot s; //receives no initialization
    Snapshot s = {}; //value initializes all members

    El segundo hará que todos los miembros de cero, la primera deja en no especificado de valores. Tenga en cuenta que es recursiva:

    struct Parent { Snapshot s; };
    Parent p; //receives no initialization
    Parent p = {}; //value initializes all members

    El segundo, va a p.s.{x,y} cero. Usted puede utilizar estos agregado de inicializador de listas si tienes constructores en su estructura. Si ese es el caso, usted tendrá que agregar adecuada initalization a los constructores

    struct Snapshot {
        int x;
        double y;
        Snapshot():x(0),y(0) { }
        //other ctors /functions...
    };

    Inicializará ambos x e y a 0. Tenga en cuenta que usted puede utilizar x(), y() para inicializar ellos sin tener en cuenta su tipo: Que, a continuación, el valor de inicialización, y por lo general se obtiene un adecuado valor inicial (0 para int, 0.0 doble, llamando al constructor por defecto para los tipos definidos por el usuario que tiene el usuario declara constructores, …). Esto es especialmente importante si su estructura es una plantilla.

    • Esto produce un montón de advertencias en mi compilador.
    • Roger: Trate de usar el nombre de la estructura en el inicializador, que es lo que yo hago y no me da ninguna advertencia en VC 2012: Instantáneas s = Instantánea();
    • Schaub – litb Se Snapshot s = {}; trabajo para no POD miembros (para la puesta a cero de ellos)?
    • C++11 ahora le permite inicializar en la definición de la estructura o clase, así: struct Instantánea { double x{0}; //con los apoyos de tipo int y = 0 ; //o simplemente el estilo old school ‘por encargo’ que en realidad es la inicialización demasiado };
    • Gracias @ikku100 , que es realmente bueno.
    • Me di cuenta de que Snapshot s = {3.0}; parece inicializar s.x a 3.0 y s.y a 0. Es esta declaración de normas conformes o depender de la aplicación?
    • Es «Instantánea s = {};» parte de la norma?
    • Consulte en.cppreference.com/w/cpp/language/zero_initialization

  2. 37

    No, ellos no son 0 por defecto. La forma más sencilla de asegurarse de que todos los valores o su valor predeterminado es 0 para definir un constructor

    Snapshot() : x(0), y(0) {
    }

    Esto asegura que todos los usos de la Instantánea se han inicializado los valores.

    • La desventaja es que la estructura no es más un tipo de POD, porque tiene un constructor. Que va a romper algunas operaciones tales como la escritura a un archivo temporal.
    • C++11 correcciones de este, a pesar de que la estructura no es la VAINA, que es la norma de «diseño».
  3. 18

    En general, no. Sin embargo, una estructura declarado como archivo-ámbito de aplicación estática o en una función /se/se inicializa a 0 (al igual que todas las demás variables de los ámbitos):

    int x; //0
    int y = 42; //42
    struct { int a, b; } foo; //0, 0
    
    void foo() {
      struct { int a, b; } bar; //undefined
      static struct { int c, d; } quux; //0, 0
    }
    • Que en realidad no es una suposición segura. usted no debe confiar en el valor de cualquier cosa que usted no inicializar
    • Almacenamiento estático duración objetos siempre se inicializa a cero, vea stackoverflow.com/questions/60653/… para una cita de la norma. Si este es un buen estilo es otro asunto.
  4. 12

    Con la VAINA también puede escribir

    Snapshot s = {};

    Que no se debe usar memset en C++, memset tiene el inconveniente de que si hay un no-POD en la estructura que se va a destruir.

    o como este:

    struct init
    {
      template <typename T>
      operator T * ()
      {
        return new T();
      }
    };
    
    Snapshot* s = init();
    • Reloj hacia fuera para el Señor Más Desconcertantes de análisis
    • oh wat?
    • Más Desconcertantes Analizar convierte las cosas que se ven como normales ctors — SomeType foo(); es típico, aunque puede suceder con los demás, en función de las definiciones (en ese caso, una función foo que devuelve SomeType). Lo siento por el necro, pero si alguien se tropieza con esto, pensé en contestar.
    • thx
  5. 7

    En C++, no utilice el argumento de constructores. En C no se puede tener constructores, por lo que el uso de cualquiera de memset o – la solución interesante – zona de inicializadores:

    struct Snapshot s = { .x = 0.0, .y = 0.0 };
    • Creo que esto es C, no C++. Se producirá un error de compilación bajo algunos compiladores de C++. He experimentado el fallo de compilación bajo Cygwin o MinGW.
  6. 4

    Ya que esto es una VAINA (esencialmente una estructura C) hay poco daño en la inicialización de la C forma:

    Snapshot s;
    memset(&s, 0, sizeof (s));

    o similar

    Snapshot *sp = new Snapshot;
    memset(sp, 0, sizeof (*sp));

    Yo no iría tan lejos como para usar calloc() en un programa de C++, aunque.

    • No es portable. 0 puntero puede tener el no-valor de 0.
    • sí, pero esta estructura no contiene punteros.
    • Mismo se sostiene para dobles; todos los bits a cero no es necesariamente 0.0 . Sin embargo, usted puede comprobar si tiene IEEE754 dobles, caso en el cual debe trabajar.
  7. 3

    Creo que la respuesta correcta es que sus valores no están definidos. A menudo, se inicializan a 0 cuando se ejecutan las versiones de depuración del código. Esto no suele ser el caso cuando se ejecuta la liberación de versiones.

    • En realidad las versiones de depuración de casualidad ya han 0 en esos lugares en la memoria. Esta no es la misma que la inicialización!
  8. 2

    Mover pod de los miembros de una clase base para acortar su lista de inicializador:

    struct foo_pod
    {
        int x;
        int y;
        int z;
    };
    
    struct foo : foo_pod
    {
        std::string name;
        foo(std::string name)
            : foo_pod()
            , name(name)
        {
        }
    };
    
    int main()
    {
        foo f("bar");
        printf("%d %d %d %s\n", f.x, f.y, f.z, f.name.c_str());
    }

Dejar respuesta

Please enter your comment!
Please enter your name here