C++ ¿Cómo se establece una matriz de punteros a null en un initialiser lista de igual manera?

Soy consciente de que no puede usar un initialiser lista para una matriz. Sin embargo, nunca he oído hablar de maneras que usted puede establecer una matriz de punteros a NULL en una forma que es similar a un initialiser lista.

No estoy seguro de cómo se hace esto. He oído que es un puntero a NULL por defecto, aunque no sé si esto está garantizado/en el estándar de C++. No estoy seguro de si inicialización mediante el operador new en comparación con el normal de asignación puede hacer una diferencia demasiado.

Edit: me refiero a hacer esto en un archivo de encabezado/constructor de la inicialización de la lista. No me quiero poner en el constructor, y no quiero usar un Vector.

InformationsquelleAutor user233320 | 2010-04-10

6 Kommentare

  1. 37

    Con el fin de establecer una matriz de punteros a null en la lista de inicializador de constructor, puede utilizar el () inicializador

    struct S {
      int *a[100];
    
      S() : a() {
        //`a` contains null pointers 
      }
    };

    Por desgracia, en la versión actual del lenguaje de la () inicializador es la única inicializador que puede utilizar con un miembro de la matriz en el constructor de la lista de inicializador. Pero al parecer esto es lo que usted necesita en su caso.

    La () tiene el mismo efecto en matrices asignadas con new[]

    int **a = new int*[100]();
    //`a[i]` contain null pointers 

    Que en otros contextos se puede utilizar el {} agregado de inicializador para lograr el mismo efecto

    int *a[100] = {};
    //`a` contains null pointers 

    Tenga en cuenta que no hay absolutamente ninguna necesidad de apretar un 0 o un NULL entre el {}. El vacío par de {} va a hacer muy bien.

    • Sí! Eso es exactamente lo que yo quería, gracias 🙂
    • +1 – Solo como un aparte, C requiere que haya al menos un valor entre el inicializador de llaves. C++ añade el vacío de La llave de inicializador ({ }) en concreto, porque no hay ninguna razón por la que un objeto de valor por defecto tiene que ser algo parecido a 0, y el código pidiendo para la inicialización de un objeto puede tener ninguna idea de lo que un default podría ser (en particular en las plantillas).
    • Pensé int *a = new int[100](); crea un puntero a un array de enteros que son cero inicializa significado a[i] contendría 0 y ser un eliminan las referencias puntero a la (i+1)th entero de la matriz en lugar de un puntero null.
    • Buen lugar. Me tomé la libertad de fijación que, desde la Hormiga no en el transcurso de los años. 😉 Esto muestra cómo el puntero y la sintaxis de array heredado de C es confuso en su fealdad, y cómo mucho un typedef o dos realmente podría ayudar aquí – o simplemente por qué no usar new. 😛
  2. 6

    Usted puede cambiar de la matriz a std::vector y uso

    std::vector<T*> v(SIZE);

    Los valores serán inicializados por NULLs automáticamente. Este es el preferido de C++ manera.


    Actualización: debido a que C++11, hay una manera más: el uso de

    std::array<T*, SIZE> array = {};

    Este se comporta más como una versión corregida de estilo C de la matriz (en particular, evita asignaciones dinámicas), lleva su tamaño a su alrededor y no se descompone a un puntero. El tamaño, sin embargo, necesita ser conocido en tiempo de compilación.

    • A menos que el OP no quiere dinámicamente el tamaño de la matriz.
    • Así, el OP podía simplemente ignorar la posibilidad para la dinámica de cambio de tamaño. Estilo C++matrices son generalmente una Buena Cosa.
    • Si el tamaño es conocido en tiempo de compilación sin embargo, las matrices integradas son mejores. Es mejor evitar la asignación dinámica cuando sea posible. vectors deben ser utilizados siempre que el tamaño de la constante no es conocido en tiempo de compilación, aunque.
    • no estoy seguro de eso. Con vector uno tiene al menos decente índice-fuera-de-rango de comprobación, así como copia de los constructores, etc. Que por lo general conduce a un menos propenso a errores de código. En mi humilde opinión, la necesidad de C-estilo de matrices sólo se justifica por la necesidad de una profunda manual de optimizaciones de código. Los compiladores modernos son generalmente lo suficientemente inteligente para optimizar fuera vector‘s encima de la cabeza en la mayoría de los casos.
    • los vectores tienen muchas, muchas ventajas a través de matrices, que no tienen nada que ver con la asignación dinámica. Por ejemplo, los vectores de llevar a su tamaño alrededor con ellos y no decaer en los punteros. Y uno debe evitar la asignación dinámica – sino en el propio código, no en el código de la biblioteca.
    • Por supuesto, debido a que C++11 con std::array, podemos evitar la asignación dinámica al mismo tiempo que todos los demás beneficios de los contenedores estándar, incluyendo la capacidad de realizar definido por sus límites de indexación (aunque no automáticamente a medida que tu comentario puede ser leído de implicar) utilizando .at() como en vector
    • Efectivamente, eso es cierto; sin embargo, la respuesta es a partir de 2010, donde C++11 estándar todavía no fue ampliamente aceptada. Voy a modificar la respuesta sin embargo. Gracias por la sugerencia!
    • Sé que usted escribió la respuesta antes de C++11 fue el final; sólo pensé que sería útil para al menos tener un comentario dando una actualización. 🙂
    • «El tamaño, sin embargo, necesita ser conocido en tiempo de compilación.» al igual que cualquier otra matriz

  3. 4

    Normalmente una matriz no ser inicializadas por defecto, pero si se activa uno o más elementos de forma explícita, a continuación, cualquier resto de elementos será automáticamente inicializado a 0. Desde 0 y NULL son equivalentes por lo tanto, puede inicializar un array de punteros a NULL como este:

    float * foo[42] = { NULL }; //init array of pointers to NULL
    • Ser conscientes de que «int foo1[42] = { 1 };» sólo inits la primera a 1 y el resto a 0, ya que por defecto C++ inicializa los elementos de la matriz a 0! En el ejemplo, se está poniendo sólo el primer elemento a 0 y el resto es configurado por defecto a 0.
    • No estoy seguro de por qué usted piensa que la respuesta no está clara, o por qué merece un voto ? El OP fue preguntando acerca de la inicialización de los arrays de punteros a NULL.
    • por favor, ver mi comentario. Es porque int foo1[42] = { 0 }; es engañosa.
    • bueno, yo todavía no veo por qué es engañoso, pero voy a añadir algunas aclaraciones si te gusta.
  4. 2

    No estoy seguro de cómo se hace esto. He oído que es un puntero a NULL por defecto, aunque no sé si esto está garantizado/en el estándar de C++.

    No está garantizada por el estándar de C++. Construido en tipos ( como punteros ) están llenos de basura a menos que se establezca lo contrario.

    No estoy seguro de si inicialización mediante el operador new en comparación con el normal de asignación puede hacer una diferencia demasiado.

    ¿Qué se entiende por «normal asignación» ? Si estamos hablando de una variable automática, entonces usted puede hacer esto:

    MyType * pointers[2] = {}

    y los punteros debe ser inicializado a NULL.

    • Los punteros no están garantizados para ser inicializado a NULL, igual enteros no se inicializan a 0, en muchos contextos. Tenga en cuenta que su ejemplo es equivalente a {NULL, 0} y {} (siendo este último el preferido), en lugar de especificar un valor para todos los elementos de la matriz.
    • Sé que esta respuesta es años de retraso, pero los de ahora. 🙂
  5. 0
    void* p[10] = { 0 };
    • Ser conscientes de que esto es sólo explícitamente de iniciar el primer elemento es 0, el resto son inicializadas a cero de forma predeterminada por C++. Por ejemplo, «int foo1[42] = { 1 };» sólo inits la primera a 1 y el resto a 0, ya que por defecto C++ inicializa los elementos de la matriz a 0!
    • Lo que es más importante, el compilador se inicializa el resto de entradas para todos los bits a cero, lo que no se garantiza que sea la misma que la representación de un puntero null.
    • En realidad, el restante las entradas están bien; es explícitamente dando 0 que podría ser un problema – es decir, recibe 0-inicialización si no una mención explícita a 0. :S «Cero inicialización se realiza […] para los miembros del valor-inicializa la clase de tipos que no tienen los constructores, incluyendo el valor de inicialización de los elementos de agregados para los que no inicializadores se proporcionan. […] Un cero inicializa puntero es el valor de puntero nulo de su tipo, incluso si el valor del puntero nulo no es parte integrante de cero.» en.cppreference.com/w/cpp/language/zero_initialization debido a que C++11, utilice {}.
  6. -1

    Si usted tiene un miembro de la matriz, entonces no hay manera de inicializar, a menos que sea un miembro estático. Si la matriz no es un miembro estático, entonces usted tendrá que llenar dentro del constructor del cuerpo.

    Que dijo, es probable que esté realmente mejor usar un std::vector. Otros que por razones técnicas, tales como la falta de un estándar STL para su plataforma, o el menor rendimiento de un std::vector es mejor que una matriz por cualquier y todos los criterios. Si el rendimiento es el problema, a continuación, asegúrese de que usted perfilado y saber los números que es un problema.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea