2009-05-25 14 views

risposta

17

Lo fa. Per un tipo T, T() value-initializes un "oggetto" di tipo T e restituisce un'espressione di valore.

int a = int(); 
assert(a == 0); 

Stesse per pod-classi:

struct A { int a; }; 
assert(A().a == 0); 

anche vero per alcune classi non-POD che non hanno nessun utente dichiarato costruttore:

struct A { ~A() { } int a; }; 
assert(A().a == 0); 

Dal momento che non si può fare A a() (crea una invece la dichiarazione di funzione), boost ha una classe value_initialized, che consente di aggirare il problema, e C++ 1x avrà la seguente sintassi alternativa

int a{}; 

Nelle parole secche del standard, questo suona come

L'espressione T(), dove T è un semplice tipo-specificatore (7.1.5.2) per un oggetto completo non-matrice tipo o il tipo void (possibilmente cv-qualificato), crea un rvalue del tipo specificato, che è di valore inizializzato

Poiché un typedef-name è un nome di tipo, che è un semplice tipo specificatore di per sé, funziona perfettamente.

+3

Sto studiando il progetto standard cercando di capirlo.Mi ero dimenticato del typedef e stavo cercando di capire come un tipo di puntatore potesse essere un identificatore di tipo semplice (non lo è), e ora ha senso: non puoi fare int *(), ma puoi fare T() se T è typedef'ed a int *. –

+0

Che dire dei membri di tipo POD e POD? –

+0

struct A {~ A() {} int a; }; è un tipo non pod. Se tu avessi introdotto tu stesso un costruttore, allora il valore di "a" dipende da cosa fa quel costruttore, naturalmente. –

2
#include <iostream> 
struct Foo { 
    char bar; 
    char baz; 
    char foobar; 
    // the struct is a POD 
    //virtual void a() { bar='b'; } 
}; 

int main() { 
    Foo o1; 
    Foo o2 = Foo(); 

    std::cout << "O1: " << (int)o1.bar <<" "<< (int)o1.baz <<" "<< (int)o1.foobar << std::endl; 
    std::cout << "O2: " << (int)o2.bar <<" "<< (int)o2.baz <<" "<< (int)o2.foobar << std::endl; 
    return 0; 
} 

uscita:

O1: -27 -98 0

O2: 0 0 0

calcolata() si propaga initializer chiede a tutti i membri POD. Uncomenting il metodo virtuale uscita cambia a:

O1: -44 -27 -98

O2: -71 -120 4

Tuttavia l'aggiunta di distruttore ~ ​​Foo() non sopprime il inizializzazione, sebbene crei un oggetto non POD (output simile al primo).