¿Cómo inicializar member-struct en la lista de inicializadores de la clase C++?


Tengo las siguientes definiciones de clase en c++:

struct Foo {
  int x;
  char array[24];
  short* y;
};

class Bar {
  Bar();

  int x;
  Foo foo;
};

Y quisiera inicializar la estructura "foo" (con todos sus miembros) a cero en el inicializador de la clase Bar. Se puede hacer esto de esta manera:

Bar::Bar()
  : foo(),
    x(8) {
}

... ?

O ¿qué hace exactamente el foo(x) en la lista del inicializador?

¿O la estructura se inicializa automáticamente a cero desde el compilador?

Author: Jan Rüegg, 2010-11-17

2 answers

En Primer lugar, usted debe (debe !) lea esto c++ faq con respecto a POD y agregados. En su caso, {[0] } es de hecho una clase POD y foo() es una inicialización de valor :

Para inicializar un objeto de tipo T significa:

  • si T es un tipo de clase (cláusula 9) con un constructor declarado por el usuario (12.1), entonces el constructor predeterminado
    se llama a for T (y la inicialización está mal formada si T no tiene un valor predeterminado accesible constructor);
  • si T es un tipo de clase sin unión sin un constructor declarado por el usuario, entonces cada miembro de datos no estático y componente de clase base de T se inicializa por valor;
  • si T es un tipo de matriz, entonces cada elemento se inicializa por valor;
  • de lo contrario, el objeto es cero-inicializado

Así que sí, foo será cero inicializado. Tenga en cuenta que si eliminó esta inicialización de Bar constructor, foo solo sería por defecto-inicializado :

Si no se especifica ningún inicializador para objeto, y el objeto es de (posiblemente tipo de clase no POD (o matriz de los mismos), el objeto será por defecto-inicializado; si el objeto es de tipo const-calificado, el tipo de clase subyacente: constructor predeterminado declarado por el usuario. De lo contrario, si no hay inicializador especificado para un objeto no estático, el objeto y sus subobjetos, si los hay, tener un indeterminado inicial valor;

 50
Author: icecrime,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:19

En C++ estándar necesitas hacer un ctor para Foo.

struct Foo {

  Foo(int const a, std::initializer_list<char> const b, short* c)
    : x(a), y(c) {
    assert(b.size() >= 24, "err");
    std::copy(b.begin(), b.begin() + 24, array);
  }

  ~Foo() { delete y; }

  int x;
  char array[24];
  short* y;
};

class Bar {

  Bar() : x(5), foo(5, {'a', 'b', ..., 'y', 'z'},
    new short(5)) { }

  private:

  int x;
  Foo foo;
};

En C++0x puede usar una lista de inicialización uniforme, pero aún necesita dtor para Foo:

class Bar {

  Bar() : x(5), foo{5, new char[24]{'a', 'b', ..., 'y', 'z'},
    new short(5)} { }
  ~Bar() { delete[] foo.array; delete foo.y;}
  }
  private:

  int x;
  Foo foo;
};

Para inicializar por defecto foo (como Bar() : foo(), x(8) { }) debe darle a Foo un ctor por defecto.

 8
Author: erjot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-17 13:31:35