Domanda

Sono abbastanza certo che le matrici di tipi predefiniti siano unitizzate, mentre le matrici di UDT sono inizializzate di default.

int foo [5]; // conterrà junk
Foo foo [5]; // conterrà 5 oggetti Foo inizializzati di default

Ciò si verifica indipendentemente dal fatto che l'array sia allocato nello stack o nell'heap.

Tuttavia, trovo difficile trovare una fonte autorevole su questo. Bjarne afferma che:

" I membri di matrici e strutture sono inizializzati di default o no a seconda che l'array o la struttura siano statici " che non mi dice molto.

Ho anche cercato di trovare qualcosa nello standard, ma finora nessun risultato è stato inutile.

Qualcuno conosce una fonte autorevole per confermare quanto sopra?

È stato utile?

Soluzione

ISO C ++ 03 è tanto autorevole quanto si ottiene:

  

Una POD-struct è una classe aggregata che non ha membri di dati non statici di tipo non-POD-struct, non-POD-union (o array di tali tipi) o riferimento e non ha assegnazione di copia definita dall'utente operatore e nessun distruttore definito dall'utente. Allo stesso modo, un'unione POD è un'unione aggregata che non ha membri di dati non statici di tipo non-POD-struct, non-POD-union (o array di tali tipi) o riferimento e non ha un operatore di assegnazione della copia definito dall'utente e nessun distruttore definito dall'utente. Una classe POD è una classe che è una struttura POD o un'unione POD.

     

I tipi aritmetici (3.9.1), i tipi di enumerazione, i tipi di puntatore e i tipi di puntatore a membro (3.9.2) e le versioni qualificate per cv di questi tipi (3.9.3) sono chiamati collettivamente tipi scalari. I tipi scalari, i tipi di struttura POD, i tipi di unione POD (clausola 9), le matrici di tali tipi e le versioni qualificate in cv di questi tipi (3.9.3) sono collettivamente chiamati tipi POD.

     

Inizializzare a zero un oggetto di tipo T significa:

     
      
  • se T è un tipo scalare (3.9), l'oggetto è impostato sul valore 0 (zero) convertito in T;
  •   
  • se T è un tipo di classe non sindacale, ciascun membro di dati non statico e ogni classe di base   subobject è a zero inizializzato;
  •   
  • se T è un tipo di unione, il primo membro di dati con nome dell'oggetto viene inizializzato con zero;
  •   
  • se T è un tipo di array, ogni elemento è inizializzato con zero;
  •   
  • se T è un tipo di riferimento, non viene eseguita alcuna inizializzazione.
  •   
     

Inizializzare per default un oggetto di tipo T significa:

     
      
  • se T è un tipo di classe non POD (clausola 9), viene chiamato il costruttore predefinito per T (e l'inizializzazione non è corretta se T non ha un costruttore predefinito accessibile);
  •   
  • se T è un tipo di array, ogni elemento è inizializzato come predefinito;
  •   
  • altrimenti, l'oggetto viene inizializzato con zero.
  •   
     

Inizializzare un oggetto di tipo T significa:

     
      
  • se T è un tipo di classe (clausola 9) con un costruttore dichiarato dall'utente (12.1), viene chiamato il costruttore predefinito per T (e l'inizializzazione non è corretta se T non ha un costruttore predefinito accessibile);
  •   
  • se T è un tipo di classe non sindacale senza un costruttore dichiarato dall'utente, allora ogni membro di dati non statico e componente di classe base di T è inizializzato dal valore;
  •   
  • se T è un tipo di array, ogni elemento è inizializzato dal valore;
  •   
  • altrimenti, l'oggetto viene inizializzato con zero
  •   
     

Ogni oggetto con durata di memorizzazione statica deve essere inizializzato a zero all'avvio del programma prima che avvenga qualsiasi altra inizializzazione. [Nota: in alcuni casi, l'inizializzazione aggiuntiva viene eseguita in seguito.]

     

Un oggetto il cui inizializzatore è un insieme vuoto di parentesi, ovvero (), deve essere inizializzato dal valore.

     

Se non viene specificato alcun inizializzatore per un oggetto e l'oggetto appartiene a un tipo di classe non POD (possibilmente qualificato in cv) (o array di questi), l'oggetto deve essere inizializzato per impostazione predefinita; se l'oggetto è di tipo const-qualificato, il tipo di classe sottostante deve avere un costruttore predefinito dichiarato dall'utente. Altrimenti, se non viene specificato alcun inizializzatore per un oggetto non statico, l'oggetto e gli eventuali oggetti secondari hanno un valore iniziale indeterminato); se l'oggetto o uno qualsiasi dei suoi oggetti secondari sono di tipo const-qualificato, il programma è mal formato.

Ad esempio, int è sicuramente un tipo POD (è un tipo aritmetico) e quindi un campo locale o di tipo int , in assenza di inizializzatore, avrà un valore indeterminato. Per Foo , questo dipende da come viene definito - approssimativamente parlando, se non ha un costruttore e tutti i suoi membri sono di tipo POD, allora è esso stesso un tipo POD e nessuna inizializzazione avviene anche. Altrimenti, viene chiamato il costruttore predefinito. Anche allora, ciò non significa che membri siano inizializzati - le regole sono ricorsive, quindi i membri POD di tipo non-POD non saranno inizializzati a meno che il costruttore di quel tipo non lo faccia specificamente (nel suo inizializzatore lista).

Le variabili e i campi statici saranno in ogni caso inizializzati con zero. Si noti che ciò vale anche per i non-POD, il che significa che una variabile statica di un tipo di classe garantisce che tutti i campi siano ricorsivamente impostati su (T) 0 anche prima dell'esecuzione del costruttore.

Un trucco utile per inizializzare in modo predefinito qualsiasi tipo POD aggregato consiste nell'utilizzare {} nell'inizializzatore; si noti che funziona sia con le strutture che con le matrici:

char s[10] = {}; // all elements default-initialized
Foo foo = {};    // all fields recursively default-initialized

Altri suggerimenti

Dice nello standard C ++, in 8.5.9:

  

Se non viene specificato alcun inizializzatore per un   oggetto e l'oggetto è (possibilmente   tipo di classe POD non qualificato cv (o   matrice di ciò), l'oggetto deve essere   default-inizializzato; se l'oggetto lo è   di tipo qualificato, il   il tipo di classe sottostante deve avere a   costruttore predefinito dichiarato dall'utente.   Altrimenti, se non c'è inizializzatore   specificato per un oggetto non statico, il   oggetto e relativi oggetti secondari, se presenti,   hanno un valore iniziale indeterminato.

  

" I membri di matrici e strutture sono inizializzati di default o no a seconda che l'array o la struttura siano statici "

Questo è autorevole, anche se potrebbe essere più chiaro:

  • Le matrici e le strutture dichiarate come static sono inizializzate su zero.
  • Gli array e le strutture locali di tipi predefiniti ( cioè che non hanno costruttori) non sono inizializzati.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top