Domanda

Ho letto un libro S. Lippman "Inside C ++ Object Model", esiste un tale codice

class Foo { public: int val; Foo *pnext; };
void foo_bar()
{
// Oops: program needs bar's members zeroed out
Foo bar;
Foo* baz = new Foo(); // this line i added myself
if ( bar.val || bar.pnext )
// ... do something
// ...
}

E dice che "un costruttore predefinito non è sintetizzato per questo frammento di codice.

Gli oggetti globali sono garantiti per avere la memoria associata "azzerato" all'avvio del programma. Gli oggetti locali assegnati allo stack del programma e gli oggetti HEAP assegnati al negozio libero non hanno la memoria associata a zero; Piuttosto, la memoria mantiene il modello bit arbitrario del suo uso precedente ".

In questo codice l'oggetto BAZ è stato creato sul heap e secondo ciò che è stato detto sopra questo oggetto non è globale e non sarà chiamato costruttore predefinito. Capisco correttamente?

È stato utile?

Soluzione

Le parentesi in new Foo() specificare Inizializzazione del valore; Ciò significa sostanzialmente che ogni membro è pari a zero inizializzato. Se invece hai detto new Foo, quindi i membri sarebbero lasciati non inizializzati, come lo sono per la tua variabile automatica.

Sfortunatamente, per iniziare il valore della variabile automatica, non puoi scrivere Foo bar(), poiché ciò dichiara una funzione. Avrai bisogno

Foo bar{};        // C++11
Foo bar = Foo();  // Historical C++

Altri suggerimenti

Quando lo fai:

Foo* baz = new Foo();

stai assegnando dinamicamente un Foo istanza e Inizializzazione del valore esso. Per i pod, ciò significa che i membri ottengono zero inizializzati. Se lo avessi detto (supponendo un contesto non globale):

Foo* baz = new Foo;

poi il Foo L'istanza verrebbe inizializzata predefinita, il che significherebbe che non viene eseguita alcuna inizializzazione dei suoi membri, poiché sono pod.

Questo vale anche per le istanze di archiviazione automatica:

Foo f0; // default initializaiton: members not zeroed out.
Foo f1 = Foo(); // value initialization: members zeroed out.
Foo f2{}; // C++11 value initialization: members zeroed out.
Foo f3(); // Ooops! Function declaration. Something completely different.

Se una classe non ha un costruttore predefinito (e nessun altro costruttore), il compilatore ne creerà uno per te. Deve, o non saresti in grado di creare istanze della classe. Tuttavia, il costruttore predefinito generato non farà nulla.

Cosa aggiunge il set vuoto di parentesi new Foo() fa, è quello di valorizzare l'inizializzare l'oggetto allocato, il che significa che i membri vengono inizializzati sui loro valori "predefiniti", che è zero per i valori di punti interi e volanti e nullptr per i suggerimenti.

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