Cosa significano le seguenti frasi in C ++: zero, default e inizializzazione di valore?

StackOverflow https://stackoverflow.com/questions/1613341

  •  06-07-2019
  •  | 
  •  

Domanda

Cosa significano le seguenti frasi in C ++:

  • zero inizializzazione,

  • inizializzazione predefinita e

  • valore di inizializzazione

Cosa dovrebbe sapere uno sviluppatore C ++ su di loro?

È stato utile?

Soluzione

Una cosa da capire è che l'inizializzazione del valore è nuova con lo standard C ++ 2003 - non esiste nello standard originale del 1998 (penso che potrebbe essere l'unica differenza che è più di un chiarimento). Vedi Kirill La risposta di V. Lyadvinsky per le definizioni direttamente dallo standard.

Vedi questa risposta precedente sul comportamento dell'operatore nuovo per dettagli sul diverso comportamento di questo tipo di inizializzazione e su quando iniziano (e quando differiscono da c ++ 98 a C + 03):

Il punto principale della risposta è:

  

A volte la memoria restituita dal nuovo operatore viene inizializzata, a volte non dipende dal tipo di POD che stai rinnovando o se è una classe che contiene membri POD e utilizza un compilatore- costruttore predefinito generato.

     
      
  • In C ++ 1998 ci sono 2 tipi di inizializzazione: zero e default
  •   
  • In C ++ 2003 è stato aggiunto un terzo tipo di inizializzazione, inizializzazione del valore.
  •   

Per non dire altro, è piuttosto complesso e quando i diversi metodi entrano in gioco sono sottili.

Una cosa sicuramente da tenere presente è che MSVC segue le regole C ++ 98, anche in VS 2008 (VC 9 o cl.exe versione 15.x).

Il frammento seguente mostra che MSVC e Digital Mars seguono le regole C ++ 98, mentre GCC 3.4.5 e Comeau seguono le regole C ++ 03:

#include <stdio.h>
#include <string.h>
#include <new>

struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

int main()
{
    char buf[sizeof(B)];
    memset( buf, 0x5a, sizeof( buf));

    // use placement new on the memset'ed buffer to make sure 
    //  if we see a zero result it's due to an explicit 
    //  value initialization
    B* pB = new(buf) B();   //C++98 rules - pB->m is uninitialized
                            //C++03 rules - pB->m is set to 0
    printf( "m  is %d\n", pB->m);
    return 0;
}

Altri suggerimenti

C ++ 03 Standard 8.5 / 5:

  

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

     

Per default-initialize un oggetto di tipo T significa:
  & # 8212; 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);
  & # 8212; se T è un tipo di array, ogni elemento è inizializzato per impostazione predefinita;
  & # 8212; in caso contrario, l'oggetto viene inizializzato con zero.

     

Per value-initialize un oggetto di tipo T significa:
  & # 8212; 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);
  & # 8212; 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;
  & # 8212; se T è un tipo di array, ogni elemento è inizializzato dal valore;
  & # 8212; in caso contrario, l'oggetto viene inizializzato con zero

     

Un programma che richiede l'inizializzazione di default o l'inizializzazione di valore di un'entità di tipo di riferimento è mal formato. Se T è un tipo con certificazione cv, la versione cv non qualificata di T viene utilizzata per queste definizioni di inizializzazione zero, inizializzazione predefinita e inizializzazione del valore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top