2015-02-08 14 views
5

Uso Visual C++ 2013. Quando la classe è un aggregato, viene inizializzata a zero. Quando è un non aggregato, sembra essere inizializzato di default e lasciato indeterminato. Perché?C++ 14 Inizializzazione uniforme su un non aggregato

#include <iostream> 

using namespace std; 

class Test_1 
{ 
public: 
    int i; 
    void f(){}; 
}; 

class Test_2 
{ 
public: 
    int i; 
    virtual void f(){}; 
}; 

int main() 
{ 
    Test_1 t1{}; 
    Test_2 t2{}; 

    cout<<t1.i<<endl; //0 
    cout<<t2.i<<endl; //-858993460 

    getchar(); 
} 
+3

Quale compilatore e quale versione? '{}' dovrebbe essere inizializzazione del valore per non aggregati e 't2.i' dovrebbe essere stato inizializzato a zero poiché non ha un costruttore fornito dall'utente. –

+0

In questo modo MSVC è ospitato su [rextester] (http://rextester.com/runcode) per bloccarsi e quindi fornire immondizie simili. Stessa cosa con un altro [compilatore online MSVC] (http://webcompiler.cloudapp.net/). Sento odore di insetto. –

risposta

4

Se il compilatore esegue questa operazione, è danneggiato.

[dcl.init.list]/p3 (tutte le citazioni provengono N4140):

List-inizializzazione di un oggetto o di riferimento di tipo T è definito come segue:

  • Se T è un aggregato, viene eseguita l'inizializzazione aggregata (8.5.1).
  • Altrimenti, se l'elenco di inizializzazione non ha elementi e T è un tipo di classe con un costruttore predefinito, l'oggetto è inizializzato con valore .
  • [...]

[dcl.init]/p8:

Per valore-inizializzare un oggetto di tipo T significa:

  • se è T un tipo di classe (eventualmente qualificata per il cv) (clausola 9) con nessun costruttore predefinito (12.1) o un costruttore predefinito che sia fornito dall'utente o cancellato, quindi l'oggetto è predefinito-inizializzato;
  • se T è un (possibilmente cv-qualificato) tipo di classe senza un costruttore predefinito fornito dall'utente o eliminato, l'oggetto è zero inizializzata e vincoli semantici per default-inizializzazione sono controllati, e se T ha una costruttore di default non banale , l'oggetto è inizializzato di default;
  • se T è un tipo di matrice, quindi ogni elemento viene inizializzato in base al valore;
  • in caso contrario, l'oggetto è inizializzato a zero.

Test_2 non è un aggregato, così t2 avrebbe dovuto essere valore-inizializzato. A sua volta, poiché la funzione di costruzione predefinita di Test_2 non è fornita dall'utente, t2 deve essere inizializzata per la prima volta (causando l'inizializzazione di su 0), quindi viene eseguito il costruttore predefinito.

+4

L'inizializzazione del valore di classi non banali è infatti interrotta in VC++, ed è sempre stata. Purtroppo, non c'è una soluzione in vista, nonostante la natura fondamentalmente necessaria della semantica dell'inizializzazione. [Qui] (https://connect.microsoft.com/VisualStudio/feedback/dettagli/746973/errato-c-11-valore-inizializzazione-per-tipo-con-implicitamente-dichiarato-ma-non-banale-predefinito-costruttore) è uno dei _many_ inviati segnalazioni di bug, tutti chiusi come "differito" che ho visto. [In alcuni casi, nemmeno l'inizializzazione aggregata è corretta.] (Https://connect.microsoft.com/VisualStudio/Feedback/Details/956553) – ildjarn

Problemi correlati